ios - OCMock "expected method was not invoked"即使我自己调用它

标签 ios cocoa unit-testing mocking ocmock

我正在尝试在 iOS 项目中设置一个简单的 OCMock 单元测试,以熟悉框架。

我有一个模拟的 DataLoader 类,即使我自己调用该方法,我的期望也失败了:

- (void)testSimpleMocking {
    // Mock the class
    id mock = [OCMockObject niceMockForClass:[DataLoader class]];

    // Override the 'dispatchLoadToAppDelegate:' to be a no-op
    [[[mock stub] andReturn:nil] dispatchLoadToAppDelegate:[OCMArg any]];

    // Expect the method to be called
    [[mock expect] dispatchLoadToAppDelegate:[OCMArg any]];

    // Call the method
    [mock dispatchLoadToAppDelegate:nil];

    // Verify
    [mock verify];
}

但是,当我运行这个测试时,我收到错误:

/Users/Craig/projects/MyApp/Unknown.m: -[MockingDataLoaderTest testSimpleMocking] : OCMockObject[DataLoader]:
expected method was not invoked: dispatchLoadToAppDelegate:<OCMAnyConstraint: 0x1a3d890>

当我自己调用方法时,这怎么可能?

编辑:一个更复杂的案例:

- (void)testDataLoaderWaitsForDownload {
    id mock = [OCMockObject niceMockForClass:[DataLoader class]];
    id metadataItem = [OCMockObject niceMockForClass:[NSMetadataItem class]];

    // Prepare NSMetadataItem
    [[[metadataItem expect] andReturn:nil] valueForAttribute:NSMetadataItemURLKey];

    // CODERUN
    [mock waitForDownload:metadataItem thenLoad:YES];

    //VERIFY
    [metadataItem verify];
}

以及 waitForDownload:thenLoad: 方法的实现:

- (void)waitForDownload:(NSMetadataItem *)file thenLoad:(BOOL)load {
    NSURL *metadataItemURL = [file valueForAttribute:NSMetadataItemURLKey];
    ...

失败并出现错误:

Unknown.m:0: error: -[MockingDataLoaderTest testDataLoaderWaitsForDownload] : OCMockObject[NSMetadataItem]: expected method was not invoked: valueForAttribute:@"kMDItemURL"

最佳答案

在您的测试中,stub 优先,因为它首先被调用。如果您调换 expectstub 的顺序,您的测试应该会通过。

同时使用 expectstub 的原因(具有相同的参数 expectations)是为了确保至少发生一次调用,然后响应后续的调用调用没有失败。

如果您真的只想调用一个方法,只需将 andReturn: 添加到 expect 子句中...

- (void)test_dispatchLoadToAppDelegate_isCalledExactlyOnce {
    // Mock the class
    id mock = [OCMockObject niceMockForClass:[DataLoader class]];

    // Expect the method to be called
    [[[mock expect] andReturn:nil] dispatchLoadToAppDelegate:[OCMArg any]];

    // Call the method
    [mock dispatchLoadToAppDelegate:nil];

    // Verify
    [mock verify];
}

另一种情况:

- (void)test_dispatchLoadToAppDelegate_isCalledAtLeastOnce {
    // Mock the class
    id mock = [OCMockObject niceMockForClass:[DataLoader class]];

    // Expect the method to be called
    [[[mock expect] andReturn:nil] dispatchLoadToAppDelegate:[OCMArg any]];

    // Handle subsequent calls
    [[[mock stub] andReturn:nil] dispatchLoadToAppDelegate:[OCMArg any]];

    // Call the method
    [mock dispatchLoadToAppDelegate:nil];

    // Call the method (again for fun!)
    [mock dispatchLoadToAppDelegate:nil];

    // Verify
    [mock verify];
}

对于这种特殊情况,看起来您可以使用 niceMockForClass 但如果您希望 stub 返回一个非零值,那么您必须调用 stub无论哪种方式。

关于ios - OCMock "expected method was not invoked"即使我自己调用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17297618/

相关文章:

ios - Xcode 说找不到代码签名身份

iphone - 使用 SBJSON 进行 JSON 解析和检查

objective-c - 自定义 cocoa 对象的默认值

c# - 如何解析 MSTest Visual Studio 2012 中的 dll 绑定(bind)

javascript - 我们如何在 Redux 异步操作中模拟获取?

PHPUnit 模拟方法返回 null

ios - 滚动 collectionView 单元格时更改 collectionView 外部的图像

ios - SecTrustEvaluate 在 iOS 5 上返回 kSecTrustResultRecoverableTrustFailure

objective-c - 为什么 Cocoa 不喜欢这个 URL?

objective-c - BOOL 应该使用什么格式说明符?