如何使用OCMock测试UIButton的setTitle

时间:2013-09-09 13:14:04

标签: ios objective-c uibutton ocmock

在与OCUnit和OCMock进行一次小型速成课程后,我不得不提出一个问题。也许这是一件容易的事情,但我无法理解这一点。

用这个小小的方法:

- (void)setLoginButtonTitleForState:(BOOL)isLoggedIn {

if (isLoggedIn) {

    [_loginButton setTitle:@"Logout" forState:UIControlStateNormal];
}
else {
    [_loginButton setTitle:@"Login" forState:UIControlStateNormal];
}

}

我想测试标题标签是否填写正确。由于我正在学习如何为这种情况编写测试,我在编写测试之前编写了该方法。但无论如何我必须实施这些测试。

如果之前有人这样做过,请帮助我。 这是我到目前为止所做的:

- (void)test_checkLoginAndSetLoginButtonAndTitle_loggedIn {
    MyViewController *myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
    id mock_vc = [OCMockObject partialMockForObject:myViewController];


    UIButton *loginButton = [[UIButton alloc] init];
    id mock_button = [OCMockObject partialMockForObject:loginButton];

    [mock_vc setLoginButton:mock_button];

    [[mock_vc expect] setLoginButtonTitleForState:YES];

    [[mock_button expect] setTitle:@"Logout" forState:UIControlStateNormal];

    [mock_vc verify];
}

所以问题是:我在这里做错了什么?

BTW:当我运行测试时,我收到以下错误:

/Unknown.m: OCPartialMockObject[MyViewController]: expected method was not invoked: setLoginButtonTitleForState:YES

我不知道为什么它不会调用该方法,因为它是公共的和可访问的。

如果有人提示我,请告诉我!

2 个答案:

答案 0 :(得分:3)

所以,也许这并没有直接回答你的问题[UIButton setTitle:forState:],但我会提出你不应该测试股票Apple API。为了测试你设置登录按钮标题的逻辑,我实际上会改变它,以便它返回一个字符串,在不同的方法中将设置按钮上的任何标题。这就是我的意思:

- (void)setLoginButtonTitleForState:(BOOL)isLoggedIn {
  [_loginButton setTitle:[self buttonTitleForLoggedIn:isLoggedIn] forState:UIControlStateNormal];
}

- (NSString *)buttonTitleForLoggedIn:(BOOL)loggedIn {
  return (loggedIn) ? @"Logout" : @"Login";
}

你的测试看起来像这样:

- (void)test_checkLoginAndSetLoginButtonAndTitle_loggedIn {
    MyViewController *myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
    STAssertEqualObjects([myViewController buttonTitleForLoggedIn:YES], @"Logout", @"After logging in, the 'login' button's title should be set to logout");
}

答案 1 :(得分:2)

Don't over-mock everything。为什么不检查是否设置了正确的字符串?这就是你真正关心的,对(最终结果,而不是你如何到达那里)?

您可以从按钮获取标签,然后使用titleForState:

将其再次与预期值进行比较
NSString *actual = [loginButton titleForState:UIControlStateNormal];
STAssertEqualObjects(actual, @"Logout", @"The button should say 'Logout' by now");