1

SOで同様の質問を見たことがありますが、どの回答も私の問題を解決していないようです。

カスタム関数を使用して mogenerator によって生成された NSManagedObject クラスがあります(モデルにはありません):

@interface MyManagedClass : _MyManagedClass {
-(NSNumber*)getRandomNumber2;
-(void)function_I_want_to_test;
}

私の function_I_want_to_test() は random() の結果に依存しており、これはテスト中に制御する必要があるものです。random() をモックできないので、OCMock と静的クラス関数に多くの問題があったため、静的ではない関数ラッパーを作成しました。

単体テストのセットアップは次のようになります。

[MagicalRecord setDefaultModelFromClass:[self class]];
[MagicalRecord setupCoreDataStackWithInMemoryStore];

デバッガーを使用して、モデルが正しく読み込まれていることを確認できました。また、非魔法の方法で行う場合:

    NSBundle *b = [NSBundle bundleForClass:[self class]];
    model = [NSManagedObjectModel mergedModelFromBundles:@[b]];

この時点以降、 random() ラッパー関数をスタブ化するためのモックを作成できません

クラスモックを試してみました

id mock = [OCMockObject mockForClass:[MyManagedClass class]];
[[[mock stub] andReturn:@50] getRandomNumber2];
MyManagedClass *my_object = [mock MR_createEntity];

部分モックを使ってみました

MyManagedClass *my_object = [MyManagedClass MR_createEntity];
id mock2 = [OCMockObject partialMockForObject:my_object];

最後のポイントの後、mock2 のインスタンスを作成するだけで、my_object の動的プロパティが破壊され、役に立たなくなります。

また、スタブしたい関数でモックプロトコルを使用しようとしましたが、まだ役に立ちません。

実行時例外は、Core Data オブジェクトを使用したテストで使用するときに他の人が取得する通常の例外です。プロパティは認識されないセレクターです。

ただし、私にとって奇妙なことは、動的プロパティをスタブしようとしているのではなく、コンパイル時に既知の通常の関数をスタブしようとしているということです。したがって、OCMock を使用するとインスタンスが役に立たなくなるのは奇妙に思えます。

理想的には、OCMock/Mogenerator/Magicalrecord を使用するものが欲しいです。

私は何を間違っていますか?

4

2 に答える 2

2

管理対象オブジェクトをモックアウトしようとしないことをお勧めします。管理対象オブジェクトを機能させるために、多くの実行時処理が行われています。そのため、テストにはメモリ内データベース アプローチを使用することをお勧めします。これにより、エンティティの空のインスタンスを作成しながら、コア データを発生させることができます。

おそらく単体テストを使用しているので、代わりにスタック全体を再作成するために一部のデータをモックアウトする必要があると思われる各テストケースで、テストを実行するために必要な状態で新しいエンティティを設定することをお勧めします。また、デフォルトのスタック作成メソッドが提供するものとは別に、メモリ永続ストア内にテストを作成し、この 2 番目のものをデフォルト スタックにアタッチすることもできます。つまり、新しいメモリ ストアを作成し、フェイク/モック データ エンティティで初期化し、それをテスト データ スタックにアタッチします。

このとりとめのないことが少し役立つことを願っていますが、肝心なのは管理対象オブジェクトをモックしないことです...本当に。

于 2012-10-11T23:21:42.833 に答える
0

乱数生成を Core Data オブジェクトからヘルパー クラスに移動することで、これを行うことができます。

@implementation RandomNumberGenerator

static RandomNumberGenerator *_sharedInstance = nil;

+(RandomNumberGenerator *)sharedInstance {
    if (_sharedInstance == nil) {
        _sharedInstance = [[RandomNumberGenerator alloc] init];
    }    
    return _sharedInstance;
}

+(void)setSharedInstance:(RandomNumberGenerator *)instance {
    [instance retain];
    [_sharedInstance release];
    _sharedInstance = instance;    
}

-(NSNumber *)generateRandomNumber {
    return ...
}

@end

次に、テストで:

-(void)testSomething {
    id mockGenerator = [OCMockObject mockForClass:[RandomNumberGenerator class]];
    [RandomNumberGenerator setSharedInstance:mockGenerator];
    [[[mockGenerator stub] andReturn:@(4)] generateRandomNumber];

    MyManagedClass *my_object = [MyManagedClass MR_createEntity];

    expect(my_object.someField).to.equal(someValueBasedOnGeneratedRandomNumber);
}
于 2012-10-11T23:38:57.363 に答える