首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何对目标C中依赖可变变量的方法进行单元测试?

如何对目标C中依赖可变变量的方法进行单元测试?
EN

Stack Overflow用户
提问于 2014-02-07 21:41:00
回答 2查看 476关注 0票数 0

下面是我的课程的一个简化版本:

代码语言:javascript
复制
@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

属性cancelledatomicvolatile,因为它可以被其他线程访问(即主线程可以调用cancel方法来停止操作)。(我相信这些都是必要的,如果没有,请注意为什么你的回答中没有。)

我正在尝试编写单元测试,以确保在编写视图控制器类之前这是可行的。

如何编写单元测试来模拟对cancel的调用,而RTMovieBuilder正在创建movies

编辑

这里有一个单元测试,我已经编写了这些测试,以确保如果首先调用notifyDelegateCreatedObjects:,就不会调用cancel

代码语言:javascript
复制
- (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()];
}

我正在使用OCHamcrestOCMockito。这个测试通过了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-07 22:08:30

我将避免在单元测试中模拟线程计时,而更多地关注于找出所有可能的结束状态可能是什么,而不管时间发生在何处,并在这些条件下为代码编写测试。正如bbum所指出的,这避免了测试中无尽的复杂性。

在您的情况下,您需要测试的条件是在操作被取消之后是否发生对notifyDelegateCreatedObjects的调用,因为取消来得太晚了。因此,只需在notifyDelegateCreatedObjects方法的下游对该场景的处理进行单元测试,或者任何由于线程计时而通知中止事件的类。

我知道这不是您问题的具体答案,但我认为这是实现相同单元测试目标的更好方法。

票数 2
EN

Stack Overflow用户

发布于 2014-02-07 21:57:42

如果您的属性是volatile,并且始终遍历setter/getter,则没有理由使用atomic

同样,正如注释中所指出的,这是对车轮的重新发明。

一般来说,试图取消单元测试而希望完全覆盖是非常困难的,因为您不能真正有效地测试所有可能的定时交互。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21638266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档