下面是我的课程的一个简化版本:
@interface RTMovieBuilder : NSObject
@property (atomic, getter = isCancelled) volatile BOOL cancelled;
@property (nonatomic, weak) id<BuilderDelegate>delegate;
- (void)moviesFromJSON:(id)JSON;
- (Movie *)movieFromDictionary:(NSDictionary *)dict;
- (void)cancel;
@end
@implementation RTMovieBuilder
- (void)moviesFromJSON:(id)JSON
{
// Check for errors -> If good, then do...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[self syncrouslyCreateMoviesFromJSON:JSON];
});
}
- (void)syncrouslyCreateMoviesFromJSON:(id)JSON
{
NSMutableArray *movies = [NSMutableArray array];
for (NSDictionary *dict in JSON)
{
if ([self isCancelled])
return;
else
[movies addObject:[self movieFromDictionary:dict]];
}
[self notifyDelegateCreatedObjects:movies];
}
- (Movie *)movieFromDictionary:(NSDictionary *)dict
{
Movie *movie = [[Movie alloc] init];
// Set movie properties based on dictionary...
return movie;
}
- (void)cancel
{
[self setCancelled:YES];
}
// ... Other methods omitted for brevity's sake
@end属性cancelled是atomic和volatile,因为它可以被其他线程访问(即主线程可以调用cancel方法来停止操作)。(我相信这些都是必要的,如果没有,请注意为什么你的回答中没有。)
我正在尝试编写单元测试,以确保在编写视图控制器类之前这是可行的。
如何编写单元测试来模拟对cancel的调用,而RTMovieBuilder正在创建movies
编辑
这里有一个单元测试,我已经编写了这些测试,以确保如果首先调用notifyDelegateCreatedObjects:,就不会调用cancel。
- (void)testIfCancelledDoesntNotifyDelegateOfSuccess
{
// given
RTMovieBuilder *builder = [[RTMovieBuilder alloc] init];
builder.delegate = mockProtocol(@protocol(BuilderDelegate));
// when
[builder cancel];
[builder notifyDelegateCreatedObjects:@[]];
// then
[verifyCount(builder.delegate, never()) builder:builder createdObjects:anything()];
}我正在使用OCHamcrest和OCMockito。这个测试通过了。
发布于 2014-02-07 22:08:30
我将避免在单元测试中模拟线程计时,而更多地关注于找出所有可能的结束状态可能是什么,而不管时间发生在何处,并在这些条件下为代码编写测试。正如bbum所指出的,这避免了测试中无尽的复杂性。
在您的情况下,您需要测试的条件是在操作被取消之后是否发生对notifyDelegateCreatedObjects的调用,因为取消来得太晚了。因此,只需在notifyDelegateCreatedObjects方法的下游对该场景的处理进行单元测试,或者任何由于线程计时而通知中止事件的类。
我知道这不是您问题的具体答案,但我认为这是实现相同单元测试目标的更好方法。
发布于 2014-02-07 21:57:42
如果您的属性是volatile,并且始终遍历setter/getter,则没有理由使用atomic。
同样,正如注释中所指出的,这是对车轮的重新发明。
一般来说,试图取消单元测试而希望完全覆盖是非常困难的,因为您不能真正有效地测试所有可能的定时交互。
https://stackoverflow.com/questions/21638266
复制相似问题