OCMock"预期的方法没有被调用",即使我自己称之为

Cra*_*tis 5 cocoa unit-testing mocking ocmock ios

我正在尝试在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];
}
Run Code Online (Sandbox Code Playgroud)

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

/Users/Craig/projects/MyApp/Unknown.m: -[MockingDataLoaderTest testSimpleMocking] : OCMockObject[DataLoader]:
expected method was not invoked: dispatchLoadToAppDelegate:<OCMAnyConstraint: 0x1a3d890>
Run Code Online (Sandbox Code Playgroud)

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

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

- (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];
}
Run Code Online (Sandbox Code Playgroud)

并执行该waitForDownload:thenLoad:方法:

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

失败并出现错误:

Unknown.m:0: error: -[MockingDataLoaderTest testDataLoaderWaitsForDownload] : OCMockObject[NSMetadataItem]: expected method was not invoked: valueForAttribute:@"kMDItemURL"
Run Code Online (Sandbox Code Playgroud)

Ben*_*ynn 7

在您的测试中,stub优先考虑因为它首先被调用.如果您打开的顺序expectstub您的测试应该通过.

你会使用这两个原因expect,并stub一起(具有相同参数的预期)是确保至少一个呼叫发生,但随后无故障后续调用响应.

如果你真的只想要一个方法调用,只需添加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];
}
Run Code Online (Sandbox Code Playgroud)

另一种情况:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

对于这种特殊情况,它看起来像你可以使用,niceMockForClass但如果你想要存根返回非零,那么你必须调用stub任何一种方式.