首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UIView.animateWithDuration:animations:completion:在XCTest中被取消

UIView.animateWithDuration:animations:completion:在XCTest中被取消
EN

Stack Overflow用户
提问于 2019-05-20 16:59:58
回答 1查看 828关注 0票数 3

我正在尝试对UIView上的一个扩展进行单元测试,该扩展名为animateWithDuration:animations:completion:

不幸的是,测试用例中的所有动画都会立即被取消,因此完成块的isFinished参数始终为false

有谁知道如何让动画在测试用例中工作吗?

这是我的游乐场代码:

代码语言:javascript
复制
import UIKit
import XCTest

extension UIView {
    func fadeOut(duration: TimeInterval, completion: ((Bool) -> Void)?) {
        UIView.animate(withDuration: duration,
                       animations: {
                            self.alpha = 0.0
                       },
                       completion: { isFinished in
                            self.isHidden = isFinished

                            completion?(isFinished)
                       })
    }
}

class UIViewTests: XCTestCase {

    func testFadeView() {
        // Given
        let expectation = self.expectation(description: "Expect completion handler to be called.")

        let view = UIView()
        view.alpha = 1.0

        // When
        print("Date before", Date())
        view.fadeOut(duration: 1.0) { (isFinished) in
            print("Date completed", Date())
            print("isFinished", isFinished)

            expectation.fulfill()
        }

        // Then
        wait(for: [expectation], timeout: 1.1)

        XCTAssertTrue(view.isHidden) // <- this assertion always fails, cause `isFinished` inside the completion handler is always `false`.
        XCTAssertEqual(view.alpha, 0.0, accuracy: CGFloat.ulpOfOne)
    }
}

UIViewTests.defaultTestSuite.run()

断言XCTAssertTrue(view.isHidden)总是失败。此外,日志语句输出:

代码语言:javascript
复制
Date before 2019-05-20 23:30:35 +0000
Date completed 2019-05-20 23:30:35 +0000

所以基本上动画是立即被杀死的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-21 12:56:21

为了使用正确的标志完成动画,视图需要在可见的UIWindow中。

代码语言:javascript
复制
let window = UIWindow()
window.addSubview(view)
window.isHidden = false

这样,您的测试就成功了。但是在测试结束时,如果不给run循环额外的刺激,UIKit将不会清理窗口。所以添加

代码语言:javascript
复制
func tearDown() {
    super.tearDown()
    RunLoop.current.run(until: Date())
}

然后,该窗口(以及其中的所有内容)将被释放。

现在它起作用了,你可以通过减少你的持续时间来节省时间。我用duration: 0.001把测试时间缩短到23ms。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56217515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档