gpt4 book ai didi

ios - 使用两个不同的参数验证方法被调用两次

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:58:09 25 4
gpt4 key购买 nike

我想测试一个方法被调用两次,第一次为参数传递 YES,第二次 NO。让事情变得复杂的是,我想测试的方法是一个类方法,我不确定这是否与我看到的问题有任何关系。

我的测试是这样的:

- (void)testCreatesMessagesWithCorrectHTMLForcing {
id messageClassMock = OCMClassMock([MyMessage class]);
[messageClassMock setExpectationOrderMatters:YES];
[[[messageClassMock expect] andForwardToRealObject] messageForDictionary:[OCMArg any]
forceHTMLRendering:YES
inContext:[OCMArg any]];
[[[messageClassMock expect] andForwardToRealObject] messageForDictionary:[OCMArg any]
forceHTMLRendering:NO
inContext:[OCMArg any]];
NSMutableDictionary *mockJSON = [self.mockJSON mutableCopy];
MyThread *classUnderTest = [MyThread threadForDictionary:mockJSON
inContext:self.mockContext];
OCMVerifyAll(messageClassMock);
[messageClassMock stopMocking];
}

threadForDictionary:inContext: 方法为线程中的每条消息调用messageForDictionary:forceHTMLRendering:inContext: 并需要一个对象作为返回值。这就是我添加 andForwardToRealObject 的原因,否则我会因为返回值为 nil 而出现异常。正如您可以从签名中想象的那样,它是关于将 JSON 解析为 CoreData 对象。

添加此测试会使同一测试文件中的所有其他测试失败并显示以下消息

unexpected method invoked: messageForDictionary:<OCMAnyConstraint: 0x7fab637063d0> forceHTMLRendering:NO inContext:<OCMAnyConstraint: 0x7fab63706eb0>
expected: messageForDictionary:<OCMAnyConstraint: 0x7fab6371cb20> forceHTMLRendering:YES inContext:<OCMAnyConstraint: 0x7fab6371fb50>"

我不明白为什么会这样,因为我最后调用了 stopMocking,所以其他测试应该不会受到影响。

以下更改使其他测试正确运行:

  • 删除两个期望中的任何一个。只要只有一个,两者中的哪一个都没有关系。
  • 将方法重命名为 testZ。这样它就在同一个文件中的其他测试之后按字母顺序排列;因此,最后执行并且似乎不再影响它们。

由于 setExpectationOrderMatters:YES 似乎不起作用,我尝试自己检查订单:

- (void)testCreatesMessagesWithCorrectHTMLForcing {
id messageClassMock = OCMClassMock([MyMessage class]);
__block BOOL firstInvocation = YES;
[[[messageClassMock expect] andForwardToRealObject] messageForDictionary:[OCMArg any]
forceHTMLRendering:[OCMArg checkWithBlock:^BOOL (id obj) {
NSNumber *boolNumber = obj;
expect([boolNumber boolValue]).to.equal(firstInvocation);
firstInvocation = NO;
return YES;
}]
inContext:[OCMArg any]];
NSMutableDictionary *mockJSON = [self.mockJSON mutableCopy];
MyThread *classUnderTest = [MyThread threadForDictionary:mockJSON
inContext:self.mockContext];
expect(firstInvocation).to.equal(NO);
OCMVerifyAll(messageClassMock);
[messageClassMock stopMocking];
}

但是 checkWithBlock: 似乎没有被调用。 (测试失败于 expect(firstInvocation).to.equal(NO);)

这是怎么回事?

是否有另一种(更好的?)方法来使用 OCMock 编写测试,以检查是否以正确的顺序使用正确的参数调用该方法?

最佳答案

我终于得到了第一个解决方案。问题在于,如果 expectationOrderMattersYES,OCMock 会抛出异常。由于异常,测试会过早退出,并且永远不会调用 stopMocking,这会导致模拟未被正确清理。随后对模拟方法的调用将失败,并出现相同的异常,从而导致所有测试失败。

解决方案是确保调用 stopMocking,即使一切都出错了。我通过像这样使用 try-catch 实现了这一点(对宏的更改和使用 andReturn 而不是 andForwardToRealObject 无关紧要):

MyMessage *message = [MyMessage insertInManagedObjectContext:self.mockContext];
id messageClassMock = OCMStrictClassMock([MyMessage class]);
@try {
[messageClassMock setExpectationOrderMatters:YES];
OCMExpect([messageClassMock messageForDictionary:[OCMArg any]
forceHTMLRendering:NO
inContext:[OCMArg any]]).andReturn(message);
OCMExpect([messageClassMock messageForDictionary:[OCMArg any]
forceHTMLRendering:YES
inContext:[OCMArg any]]).andReturn(message);
MyThread *classUnderTest = [MyThread threadForDictionary:self.mockJSON
inContext:self.mockContext];
OCMVerifyAll(messageClassMock);
}
@catch (NSException *exception) {
XCTFail(@"An exception occured: %@", exception); // you need this, otherwise the test will incorrectly be green.
}
@finally {
[messageClassMock stopMocking];
}

注意 catch block 中的 XCTFail:您需要包含它,否则尽管发生异常,您的测试仍将是绿色的。

关于ios - 使用两个不同的参数验证方法被调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35608314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com