0

私の問題は、エラーが発生することです:

OCMckObject[NSNumberFormatter]: 予期されたメソッドが呼び出されませんでした:setallowFloats:YES

私は次のコードを書きました:

(void) testReturnStringFromNumber
{
    id mockFormatter = [OCMockObject mockForClass:[NSNumberFormatter class]];
    StringNumber *testObject = [[StringNumber alloc] init];   

    [[mockFormatter expect] setAllowsFloats:YES];
    [testObject returnStringFromNumber:80.23456];
    [mockFormatter verify];
}


@implementation StringNumber

- (NSString *) returnStringFromNumber:(float)num
{
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setAllowsFloats:YES];

    NSString *str= [formatter stringFromNumber:[NSNumber numberWithFloat:num]];

    [formatter release];
    return str;
}

@end
4

4 に答える 4

4

実装は、テスト ケースで作成したオブジェクトではなく、StringNumber独自のオブジェクトを使用するためです。NSNumberFormatter「依存関係の逆転」と呼ばれる従来のリファクタリング操作を実行する必要があります。この操作では、StringNumberオブジェクトはフォーマッターを内部で作成するのではなく、パラメーターまたは ivar として受け取ります。次に、テストの一部としてモック フォーマッタを渡すことができます。

于 2010-03-04T10:57:14.737 に答える
1

あなたが提示したコードサンプルについては、NSNumberFormatter のモックについて心配する必要はありません。[StringNumber returnStringFromNumber:]適切な文字列が返されることを確認しようとしています。この場合、テストは、その文字列を計算するために使用するメソッドを気にする必要はありません。メソッドが意図したとおりに機能することだけを考えてください。

によって返された値を返すだけnumberWithFloat:であり、NSNumberFormatter はユーティリティ クラスであるため、モックしないでください。その後numberWithFloat:、将来の動作が変更された場合、テストは失敗し、テストを変更するか、実装を変更するかを決定できます。

NSNumberFormatter をモックする場合、基本的には、メソッドが返すものを返すことをテストしているだけなので、その動作が変化すると、クラスの動作も変化し、(テスト時に) わかりません。

私はモックを次の目的で使用する傾向があります。

  • 特定の環境/構成/データセットに依存する依存関係を除外する
  • テスト時に機能しない依存関係を除外する
  • 依存コードの動作のさまざまなケース (たとえば、依存関係が nil を返す場合、依存関係が負の値を返す場合、依存関係が例外をスローする場合など) について、クラスの動作を検証します。
于 2010-05-08T00:25:35.650 に答える
0

別のアイデア:StringNumberクラスのフォーマッターを使用してivarを作成してみることができます。次に、テストのKeyValueCodingを使用してフォーマッター値を設定できるようになります。

よろしく、クエンティン

于 2010-03-07T18:21:02.110 に答える
0

モック オブジェクトを返すために、NSNumberFormatter の init メソッドを動的にオーバーライドすることができます。テストでは、id mockFormatter から ivar を作成する必要があります。したがって、テスト方法は次のようになります。

(void) testReturnStringFromNumber
{
    mockFormatter = [OCMockObject mockForClass:[NSNumberFormatter class]];
    StringNumber *testObject = [[StringNumber alloc] init];   

    [[mockFormatter expect] setAllowsFloats:YES];
    [testObject returnStringFromNumber:80.23456];
    [mockFormatter verify];
}

次に、NSNumberFormatter クラスのカテゴリを追加する必要があります

@implementation NSNumberFormatter (mock)

- (id)init {
   id object;

   if (mockFormatter) {
      object = mockFormatter
   } else {
      object = invokeSupersequent();

   return object;
}

@end

したがって、テスト対象のコードで NSNumberFormatter の init メソッドが呼び出されると、モック オブジェクトが設定されていれば、それが使用されます。

ソース: - http://cocoawithlove.com/2009/12/sample-mac-application-with-complete.html

よろしく、クエンティン

于 2010-03-07T17:54:35.127 に答える