【发布时间】:2013-03-11 18:30:46
【问题描述】:
我正在尝试在 iOS 上使用 OCMock 和 GHUnit 模拟对 mutableCopy 的调用。
尽管测试通过了,但我在清理过程中收到了 EXC_BAD_ACCESS 异常,我正在尝试找出原因。
看看这个。该测试表明可以在模拟NSString 上模拟mutableCopy。在这个测试中,我返回另一个NSString,而不是NSMutableString。这只是为了证明mutableCopy 期望被触发,并且测试通过了。
#import <GHUnitIOS/GHUnit.h>
#import "OCMock.h"
@interface TestItClass : GHTestCase @end
@implementation TestItClass
// Test that mutableCopy on an NSString is mockable.
- (void)test_1_mutableCopyOfString_shouldBeMockable_givenAStringIsReturned {
NSString *string = [OCMockObject mockForClass:NSString.class];
NSString *copy = @"foo";
[(NSString *) [[(id) string expect] andReturn:copy] mutableCopy];
// MutableCopy is mocked to return a string, not a mutable string!
// This is clearly wrong from a static typing point of view, but
// the test passes anyway, which is ok.
NSMutableString *result = [string mutableCopy];
GHAssertEquals(result, copy, nil);
[(id)string verify];
}
现在我更改了模拟期望,以便 mutableCopy 现在返回 NSMutableString。测试仍然通过,但在测试结束时,我得到了 EXC_BAD_ACCESS 异常。
- (void)test_2_mutableCopyOfString_shouldBeMockable_givenAMutableStringIsReturned {
NSString *string = [OCMockObject mockForClass:NSString.class];
NSMutableString *copy = [@"foo" mutableCopy];
[(NSString *) [[(id) string expect] andReturn:copy] mutableCopy];
// Now mutableCopy is mocked to return a mutable string!
// The test now blows up during the test teardown! Why?
NSMutableString *foo = [string mutableCopy];
GHAssertEquals(foo, copy, nil);
[(id)string verify];
}
@end
在这两个测试中,verifies 工作,关于断言。这表明这两个测试都构造良好,并且模拟预期正在按预期触发。但是,第二个测试在拆解时因内存访问错误而失败:
Simulator session started with process 7496
Debugger attached to process 7496
2013-03-11 18:23:05.519 UnitTests[7496:c07] TestItClass/test_2_mutableCopyOfString_shouldBeMockable_givenAMutableStringIsReturned ✘ 0.00s
2013-03-11 18:23:06.466 UnitTests[7496:c07] Re-running: TestItClass/test_2_mutableCopyOfString_shouldBeMockable_givenAMutableStringIsReturned <GHTest: 0x7793340>
Exception: EXC_BAD_ACCESS (code=1, address=0x11dfe3ea))
您能告诉我为什么会发生这种情况吗?
谢谢, 乔
【问题讨论】:
-
请在问题中包含您的
- (void)tearDown方法 -
没有明确的拆解;它只是 GHUnit 提供的库存。
-
@Shineeth 实际上,看起来崩溃发生在 OCMock 类之一的拆解中。我已经在下面发布了部分答案。
-
你能解释一下你在这个测试中想要达到的目标吗?通常没有任何理由模拟具有明确定义行为的核心 API 方法。可能有更好的方法来实现您想要测试的内容。
-
嗨,克里斯托弗,当然,我同意。不幸的是,在这种情况下,相对于少数经过良好测试的外部构建器类,从输入生成了一个相当复杂的输出字符串。我不希望这些的实现细节成为对使用它们的类的测试的考虑。这要求我模拟它们与累积其效果的可变字符串的交互。不理想,但我不愿意放弃关注点的封装。