objective-c - 为什么这个 OCUnit 测试失败?

标签 objective-c ios mocking tdd ocunit

它正在单步进入主视图 Controller 的 ViewDidLoad,并点击调用获取所有推文的行,但我在基类和派生类的 getAllTweets 中都放置了一个断点,以查看它是否没有像我一样点击派生类预计。

@implementation WWMainViewControllerTests {

    // system under test
    WWMainViewController *viewController;

    // dependencies
    UITableView *tableViewForTests;
    WWTweetServiceMock *tweetServiceMock;    
}

- (void)setUp {

    tweetServiceMock = [[WWTweetServiceMock alloc] init];
    viewController = [[WWMainViewController alloc] init];
    viewController.tweetService = tweetServiceMock;
    tableViewForTests = [[UITableView alloc] init];
    viewController.mainTableView = tableViewForTests;
    tableViewForTests.dataSource = viewController;
    tableViewForTests.delegate = viewController;
}

- (void)test_ViewLoadedShouldCallServiceLayer_GetAllTweets {

    [viewController loadView];
    STAssertTrue(tweetServiceMock.getAllTweetsCalled, @"Should call getAllTweets on tweetService dependency");
}

- (void)tearDown {

    tableViewForTests = nil;
    viewController = nil;
    tweetServiceMock = nil;
}

基本推文服务:

@implementation WWTweetService {

    NSMutableArray *tweetsToReturn;
}

- (id)init {

    if (self = [super init]) {
        tweetsToReturn = [[NSMutableArray alloc] init];
    }

    return self;
}
- (NSArray *)getAllTweets {

    NSLog(@"here in the base of get all tweets");
    return tweetsToReturn;
}

@end

模拟推文服务:

@interface WWTweetServiceMock : WWTweetService

@property BOOL getAllTweetsCalled;

@end

@implementation WWTweetServiceMock

@synthesize getAllTweetsCalled;

- (id)init {

    if (self = [super init]) {
        getAllTweetsCalled = NO;
    }

    return self;
}

- (NSArray *)getAllTweets {

    NSLog(@"here in the mock class.");
    getAllTweetsCalled = YES;
    return [NSArray array];
}

正在测试的主视图 Controller :

@implementation WWMainViewController
@synthesize mainTableView = _mainTableView;
@synthesize tweetService;

NSArray *allTweets;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    allTweets = [tweetService getAllTweets];
    NSLog(@"was here in view controller");
}

- (void)viewDidUnload
{
    [self setMainTableView:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

最佳答案

既然您能够在 viewDidLoad 中中断调试器,那么 tweetService ivar 的值是多少?如果为 nil,则 getAllTweets 消息将只是一个 no 操作。也许 ivar 没有正确设置或在其他地方被覆盖。

您可能应该使用该属性来访问tweetService(调用self.tweetService)而不是其底层ivar。您应该只在 getter、setter 和 init 中直接访问 ivar(如果出于某些疯狂的原因不使用 ARC,也可以使用 dealloc)。

您也不应该自己调用 loadView ,而只访问 View Controller 的 view 属性。这将启动加载过程并调用 viewDidLoad

另外,如果你做了很多 mock ,我强烈推荐 OCMock .

关于objective-c - 为什么这个 OCUnit 测试失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12646470/

相关文章:

iphone - 在为 iPhone 开发时,您遇到的最讨厌的错误是什么?

java - Mockito:如何模拟实例创建?

ios - YouTube 视频总是以低分辨率在 iFrame 中传输?

java - 如何将 BindingResult 作为请求参数传递?

python - 使用 Mock 修补函数

iphone - 如何在 iPhone 上使用音频单元

iphone - 什么时候释放以及如何使用这些实例变量来避免内存泄漏?

objective-c - 寻找更简单的 Objective-C 解决方案

iphone - 用于实时交通数据的 iOS api(如 geoloqi 和 Waze)

ios - 如何在解析网页内容时单击按钮