OCMock v2.1からはクラスメソッドの返り値を替えられます

http://ocmock.org/features/ にも載ってる。

検索するとこのへんがヒットするので投下。

先日(3月ぐらい)のアップデートで機能が追加されました。

基本的には上記ブログの記事でやっているようなMethod Swizzling の機構をOCMockが自前で管理するようになった。

実際に使うならこういうかんじ。引数は最初 OCMOCK_ANY 渡してみたら動かなかったので注意。

- (void)testCallClassMethodStubingOCMock
{
  // Google検索ページへのリクエストをスタブ化してみる
  NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.google.com/"]];
  NSData* fakeContent = [@"Hello, I'm not Google !" dataUsingEncoding:NSUTF8StringEncoding];
  
  id connection = [OCMockObject mockForClass:[NSURLConnection class]];
  [[[connection stub] andReturn:fakeContent] sendSynchronousRequest:request returningResponse:nil error:nil];
  
  STAssertTrue([fakeContent isEqualToData:[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]], nil);
}

このクラスメソッド入れ替えは stopMocking で解除できる。

  [connection stopMocking];

  STAssertFalse([fakeContent isEqualToData:[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]], nil);

同名のインスタンスメソッドを定義してて呼び出しに取られちゃうような場合は classMethod で明示的にクラスメソッドフラグたてる

[[[[mock stub] classMethod] andReturn:aValue] aMethod];

のへんで意図していたようなことがやりやすくなった。

が、自分は最初モックオブジェクトって依存でテスト書けない部分を補うような目的のみで使っていたんだけど、
"ロールをモックせよ"なんかを参考にするとモックオブジェクト+TDDを使ったクラス設計から取り組むことで(そうすると自分が実装していないクラスのモック化はしなくなる)、そもそも依存でテスト書けないみたいな状況が起きにくくなるということを学んだので積極的に使ってゆきたいですね。