1

問題に行き詰まりました。OCUnit テストがあります。iOS 7 シミュレーターでは正常に実行できますが、iOS 6 シミュレーターでは EXC_BAD_ACCESS が発生します。

Xcode のスクリーンショットは次のとおりです。 ここに画像の説明を入力

と を使用OCMockitoしてOCHamcrestいます。

何が原因だったのか分かりますか?調べて原因を探っています。

アップデート:

テストケースのコード(少なくともログから):

static NSString *const EMAIL = @"foo@example.com";
static NSString *const PASSWORD = @"secret";

@interface MDLoginViewControllerTest : SenTestCase

@end

@implementation MDLoginViewControllerTest {
    MDLoginViewController *controller;
    MDLoginView *loginView;
    UIWindow *window;

    MDAlertManager *mockedAlertManager;
    MDNetwork *mockedNetwork;
    MDStorage *mockedStorage;
}

- (void)setUp
{
    [super setUp];

    mockedAlertManager = mock([MDAlertManager class]);
    mockedNetwork = mock([MDNetwork class]);
    mockedStorage = mock([MDStorage class]);

    controller = [[MDLoginViewController alloc] initWithAlert:mockedAlertManager andNetwork:mockedNetwork andStorage:mockedStorage];

    window = [[UIWindow alloc] init];
    [window addSubview:controller.view];
}

# pragma mark - Test Helpers

- (void)login
{
    [controller requestDiscoveryWithEmail:EMAIL andPassword:PASSWORD];
}

- (void)mockLoginView
{
    loginView = mock([MDLoginView class]);
    controller.loginView = loginView;
}

- (void (^)(NSError *))runControllerForgotPasswordForEmailAndReturnBlock
{
    [controller recoverAccountPasswordForEmail:EMAIL];

    MKTArgumentCaptor *captor = [MKTArgumentCaptor new];
    [verify(mockedNetwork) forgotPasswordForEmail:EMAIL andCallback:[captor capture]];

    void (^callback)(NSError *) = [captor value];
    return callback;
}

# pragma mark - Tests itself

- (void)testAlertThatInputIsEmptyWhenLoginIsNil
{
    [controller requestDiscoveryWithEmail:nil andPassword:@"pass"];

    [verify(mockedAlertManager) showAlertMessage:EMPTY_DATA_MESSAGE    withTitle:WRONG_DATA_TITLE];
    [verifyCount(mockedNetwork, never()) discoveryWithEmail:anything() andPassword:anything() andCallback:anything()];
}

- (void)testAlertThatInputIsEmptyWhenLoginIsWhitespacesOnly
{
    [controller requestDiscoveryWithEmail:@"  " andPassword:@"pass"];

    [verify(mockedAlertManager) showAlertMessage:EMPTY_DATA_MESSAGE withTitle:WRONG_DATA_TITLE];
    [verifyCount(mockedNetwork, never()) discoveryWithEmail:anything() andPassword:anything() andCallback:anything()];
}

- (void)testAlertThatInputIsEmptyWhenPasswordIsNil
{
    [controller requestDiscoveryWithEmail:@"test@t.com" andPassword:nil];

    [verify(mockedAlertManager) showAlertMessage:EMPTY_DATA_MESSAGE withTitle:WRONG_DATA_TITLE];
    [verifyCount(mockedNetwork, never()) discoveryWithEmail:anything() andPassword:anything() andCallback:anything()];
}

- (void)testAlertThatInputIsEmptyWhenPasswordIsWhitespacesOnly
{
    [controller requestDiscoveryWithEmail:@"test@ts.com" andPassword:@"   "];

    [verify(mockedAlertManager) showAlertMessage:EMPTY_DATA_MESSAGE withTitle:WRONG_DATA_TITLE];
    [verifyCount(mockedNetwork, never()) discoveryWithEmail:anything() andPassword:anything() andCallback:anything()];
}

- (void)testAlertThatWrongEmailWhenEmailIsInvalid
{
    [controller requestDiscoveryWithEmail:@"test" andPassword:@"passs"];

    [verify(mockedAlertManager) showAlertMessage:ENTER_VALID_EMAIL_MESSAGE withTitle:WRONG_DATA_TITLE];
    [verifyCount(mockedNetwork, never()) discoveryWithEmail:anything() andPassword:anything() andCallback:anything()];
}

- (void)testCallNetworkIfInputIsValid
{
    [self login];

    [verify(mockedNetwork) discoveryWithEmail:EMAIL andPassword:PASSWORD andCallback:anything()];
}
}

Xcode からのその他の画像: ここに画像の説明を入力 ここに画像の説明を入力

更新: モックからメソッドを呼び出しているメソッドに問題があるようで、引数の 1 つは に強い参照を持つブロックselfです。

このメソッドのコードは次のとおりです。

- (void)requestDiscoveryWithEmail:(NSString *)email andPassword:(NSString *)password
{
    ...
    // store email / password on view
    _email = [email copy];
    _password = [password copy];

    [self.loginView showSpinner];

    [self.network discoveryWithEmail:email
        andPassword:password
        andCallback:^(NSDictionary *response, NSError *error) {
        // Hide the spinner
        [self.loginView hideSpinner];

        if (error) {
            [self showError:error];
        }
        else {
            if (![self isResponseComplete:response]) {
                _response = [response copy];
                [self.alertManager showAlertMessage:NSLocalizedString(@"We were unable to reach some services because maintenance or some issues", @"Unreachable services message")
                                      withTitle:NSLocalizedString(@"Issues happened", @" Issues happened title")
                                    andDelegate:self];
            }
            else {
               [self processDiscoveryResponse:response];
            }
        }
    }];
}
4

0 に答える 0