6

为什么使用 Xcode 5.0 和 XCTesting 可以通过以下单元测试?我的意思是,我理解底线: 1 == 0 未评估。但是为什么不评价呢?我怎样才能使它执行,以便它会失败?

- (void)testAnimationResult
{
    [UIView animateWithDuration:1.5 animations:^{
        // Some animation
    } completion:^(BOOL finished) {
        XCTAssertTrue(1 == 0, @"Error: 1 does not equal 0, of course!");
    }];
}
4

4 回答 4

9

从技术上讲,这将起作用。但当然,测试会坐下来运行 2 秒。如果你有几千个测试,这可以加起来。

更有效的方法是将 UIView 静态方法存根到一个类别中,使其立即生效。然后将该文件包含在您的测试目标(但不是您的应用程序目标)中,以便该类别仅编译到您的测试中。我们用:

#import "UIView+Spec.h"

@implementation UIView (Spec)

#pragma mark - Animation
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion {
    if (animations) {
        animations();
    }
    if (completion) {
        completion(YES);
    }
}

@end

以上只是立即执行动画块,如果也提供了完成块,则立即执行。

于 2013-11-13T01:20:53.260 回答
2

@dasblinkenlight 是在正确的轨道上;这是我为使其正常工作所做的:

- (void)testAnimationResult
{
    [UIView animateWithDuration:1.5 animations:^{
        // Some animation
    } completion:^(BOOL finished) {
        XCTAssertTrue(1 == 0, @"Error: 1 does not equal 0, of course!");
    }];

    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
}
于 2013-10-29T23:12:26.457 回答
2

更好的方法(现在)是使用期望。

func testAnimationResult() {
    let exp = expectation(description: "Wait for animation")

    UIView.animate(withDuration: 0.5, animations: {
        // Some animation
    }) { finished in
        XCTAssertTrue(1 == 0)
        exp.fulfill()
    }

    waitForExpectations(timeout: 1.0, handler: nil)
}
于 2018-01-03T06:29:48.840 回答
1

这里的目标是将异步操作转换为同步操作。最常用的方法是使用信号量。

- (void)testAnimationResult {
    // Create a semaphore object
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);

    [UIView animateWithDuration:1.5 animations:^{
        // Some animation
    } completion:^(BOOL finished) {
       // Signal the operation is complete
       dispatch_semaphore_signal(sem);
    }];

    // Wait for the operation to complete, but not forever
    double delayInSeconds = 5.0;  // How long until it's too long?
    dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    long timeoutResult = dispatch_semaphore_wait(sem, timeout);

    // Perform any tests (these could also go in the completion block, 
    // but it's usually clearer to put them here.
    XCTAssertTrue(timeoutResult == 0, @"Semaphore timed out without completing.");
    XCTAssertTrue(1 == 0, @"Error: 1 does not equal 0, of course!");
}

如果您想查看一些实际示例,请查看RNCryptorTests

于 2013-11-13T04:35:25.633 回答