OCMock в контексте блока

Итак, я пытаюсь собрать простой тест, чтобы убедиться, что я правильно получаю значения частоты от своего аудиоконтроллера.

На мой взгляд, я делаю такой вызов, чтобы настроить обратный вызов блока:

- (void) registerVolumeCallback {
      NSNumberBlock frequencyCallback = ^(NSNumber *frequency) {
          self.currentFrequency = frequency;
      };
      self.audioController.frequencyCallback = frequencyCallback;
  }

В моем аудиоконтроллере блок обратного вызова частоты вызывается с номером nsnumber, содержащим частоту.

В моем тестовом файле у меня есть следующее:

    - (void) testFrequencyAudioServiceCallbackActive {
          OCMockObject *mockEqualizer = [OCMockObject partialMockForObject:self.testEqualizer];
          [[[mockEqualizer stub] andCall:@selector(mockDidUpdateFrequency:)
                      onObject:self] setCurrentFrequency:[OCMArg any]];
          [self.testEqualizer startAnimating];
          [ mockEqualizer verify];
    }

И:

   - (void) mockDidUpdateFrequency: (NSNumber *) frequency {
        GHAssertTrue((frequency!= nil), @"Audio Service is messing up");
  }

Где тестовый эквалайзер является экземпляром вышеупомянутого представления. Так что я пытаюсь сделать некоторые swizzling здесь. Проблема в том, что mockDidUpdateFrequency никогда не вызывается. Я попытался поставить:

 self.currentFrequency = frequency;

за пределами блока, и swizzling действительно происходит, и я получаю вызов mockDidUpdateFrequency. Я также пробовал:

 - (void) registerVolumeCallback {
     __block UIEqualizer *blockSafeSelf = self;
     NSNumberBlock frequencyCallback = ^(NSNumber *frequency) {
       blockSafeSelf.currentFrequency = frequency;
     };
    self.audioController.frequency = frequencyCallback;
}

Не повезло. Здесь в контексте блока происходят какие-то странные вещи, о которых я не знаю. Кто-нибудь знает, что происходит?


person Greg Price    schedule 30.10.2012    source источник


Ответы (1)


Для окончательного ответа вам потребуется предоставить дополнительные сведения. Например, как вызывается registerVolumeCallback? И frequencyCallback это ваш собственный код или сторонний API?

С тем, что вы предоставили, я подозреваю, что frequencyCallback - это асинхронный вызов. Таким образом, даже несмотря на то, что startAnimating может создать условие, при котором он в конечном итоге будет вызван, вы немедленно проверяете макет до того, как обратный вызов получит возможность быть вызванным. Чтобы ваш тест делал то, что вы хотите, как написано, вам нужно понять, в какой очереди выполняется этот блок, и вам нужно дать ему возможность выполниться.

Если он вызывается асинхронно в основной очереди, вы можете позволить основному циклу выполнения вращаться перед вызовом verify:

[self.testEqualizer startAnimating];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.1]];
[mockEqualizer verify];

Если он вызывается в другой очереди, у вас есть несколько других вариантов, но было бы полезно сначала получить более четкое представление о том, как структурирован ваш код.

person Christopher Pickslay    schedule 31.10.2012
comment
Спасибо, это было связано с асинхронными вещами, которые я делал в своем аудиоконтроллере. - person Greg Price; 13.11.2012