0

クラスの「偽の」バージョンを作成し、元のバージョンをスウィズして「偽の」バージョンのクラスメソッドを呼び出し、偽のクラスを作成することで、所有していないオブジェクトのクラスメソッドをモックするパターンを確立しようとしています。それ自体がモックされている共有オブジェクトでインスタンスメソッドを呼び出します。

例えば:

@interface FakeNSURLConnection : NSURLConnection
+ (void)enableMock:(id)mock;
+ (void)disableMock;
- (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate;
- (BOOL)canHandleRequest:(NSURLRequest *)request;
@end
@implementation FakeNSURLConnection
...
+ (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate {
     return [FakeNSURLConnection.sharedInstance connectionWithRequest:request delegate:delegate];
}
- (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id<NSURLConnectionDelegate>)delegate { return nil; }

+ (BOOL)canHandleRequest:(NSURLRequest *)request { return [FakeNSURLConnection.sharedInstance canHandleRequest:request]; }
- (BOOL)canHandleRequest:(NSURLRequest *)request { return NO; }
@end

何が起こるかというと、私のenableモックはNSURLConnectionとFakeNSURLConnectionのクラスメソッドを交換し、「sharedInstance」をFakeNSURLConnectionのモックにします。このように、モックが有効に[NSURLConnection canHandleRequest:request]なると、のような呼び出しがモックメソッドに転送されます。

これはNSDateで少し注意が必要です。これは、フリーダイヤルのブリッジングを行う「抽象」クラスであるためだと思いますが、よくわかりません。オブジェクトを部分的にモックしたい場合は、Fakeクラスに実際の値を返すようにすることで、このモデルから最大のメリットを得ることができると思いました。したがって、次のようなものがあります。

@interface FakeNSDate : NSDate
...
- (id)date;
- (id)dateWithTimeInterval:(NSTimeInterval)seconds sinceDate:(NSDate *)date;
- (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds;
- (id)dateWithTimeIntervalSinceNow:(NSTimeInterval)seconds;
- (id)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)seconds;
- (id)distantFuture;
- (id)distantPast;
- (NSTimeInterval)timeIntervalSinceReferenceDate;
@end
@implementation FakeNSDate
...
+ (id)date { return [FakeNSDate.sharedInstance date]; }
- (id)date { return [[NSDate alloc] init]; }
...
@end

私はallocをスウィズリングしていないわけではありません。実際、NSDateのAPIにリストされているように、公開されているクラスメソッドをスウィズリングしているだけです。

私はこのコードを使用しています:

_baseDate = [NSDate dateWithTimeIntervalSinceNow:-1.0 * 90.0 * 60.0];
_nsDateMock = [OCMockObject partialMockForObject:[FakeNSDate sharedInstance]];
NSLog(@"_nsDateMock %@", [_nsDateMock class]);
[FakeNSDate enableMock:_nsDateMock];
[[[_nsDateMock stub] andReturn:_baseDate] date];
NSLog(@"DATE: %@", [NSDate date]);

このコードは正しく実行されますが(日付は1.5時間前であると報告されます)、次のエラーが表示されます。[NSProxy methodSignatureForSelector:] called!

問題は私がしていることですか、それともpartialMockForObjectがしていることですか?私が使用しているこのパターンは非常に役立つようです-行き止まりだとは思わないでしょう。

4

1 に答える 1

0

私は自分の問題を解決するために2つのことをしました:

_nsDateMock = [OCMockObject partialMockForObject:[FakeNSDate sharedInstance]];

私はこれを正しく設定解除していないはずであり、再部分的モックとすでに部分的モックされたオブジェクトだと思います。新しいオブジェクトを割り当てるように変更しました。

_nsDateMock = [OCMockObject partialMockForObject:[[FakeNSDate alloc] init]];

また、githubから最新のコードを使用するように切り替えました。

于 2012-12-17T23:18:49.207 に答える