Skip to content

Instantly share code, notes, and snippets.

@t-oginogin
Last active December 14, 2015 23:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t-oginogin/5167025 to your computer and use it in GitHub Desktop.
Save t-oginogin/5167025 to your computer and use it in GitHub Desktop.

詳細はWiki

https://github.com/allending/Kiwi/wiki

はまったところ

  • 全てオブジェクトである必要がある。
  • intなどはtheValue()でラップする必要がある。
  • should receiveはテストするメソッド実行前に書いておく必要がある。
  • should equalなどの実行結果の確認はテストするメソッド実行後に書いておく必要がある。
  • stubはMockオブジェクトを使わなくても、既存のオブジェクトにも追加できる。
  • stubで何か動作させたい場合は、ランタイムのメソッド入れ替えを使うしかない?  (本当はテストコードだけで何とかしたい)
  • expectFutureValueはオブジェクトを引数にとる
  • 対象オブジェクトがnilの場合、shouldは通らない。
  • stubでandReturnを使う場合は、withArgumentsで指定した引数の場合のみstubが有効になる。  引数を問わずstubを有効にする場合はwithArguments:any()とする。

基本型

  1. Mock、stub作成
  2. should receive関係設定
  3. テストしたいメソッド実行
  4. should equal関係設定

テンプレート

#include "Kiwi.h"
 
SPEC_BEGIN(TestClassSpec)
 
describe(@"TestClass", ^{
    context(@"when xxx", ^{
        it(@"should xxx", ^{
 
        });
    });
});
 
SPEC_END

Mockとstub

KWMock *test = [KWMock nullMockForClass:[TestClass class]];
[test stub:@selector(count) andReturn:theValue(1)];

値の比較

[[theValue(count) should] equal:theValue(10)]; // すぐ評価
 
[[expectFutureValue(theValue(count)) shouldEventuallyBeforeTimingOutAfter(2.0)] equal:theValue(10)]; // 2.0秒後に評価

オブジェクトの比較

[[string should] equal:@"test"]; // すぐ評価
 
[[expectFutureValue(string) shouldEventuallyBeforeTimingOutAfter(2.0)] equal:@"test"]; // 2.0秒後に評価

nil検出

[object shouldBeNil];

インスタンスメソッド実行検出

[[[test should] receive] method:@"test"];

引数は何でも良い場合はany()を使う

[[[test should] receive] method:any()];

時間差で評価する場合

[[[test shouldEventuallyBeforeTimingOutAfter(1.0)] receive] method:@"test"];

クラスメソッド実行検出

[[[TestClass should] receive] method:@"test"];

インスタンスメソッドのスタブ

TestClass *test = [[[TestClass alloc] init] autorelease];
[[test stub] method: any() param:NULL];

クラスメソッドのスタブ

[TestClass stub:@selector(method: param:)];

NSURLConnection sendAsynchronousRequestを使うテスト

ダミーでsendAsynchronousRequestを作っておき、ランタイムで差し替える こうすると実際に通信しなくてもハンドラを実行できる

TestSpec内
#import <objc/runtime.h>
 
:
 
Method original = class_getClassMethod([NSURLConnection class], @selector(sendAsynchronousRequest:queue:completionHandler:));
Method sub = class_getClassMethod([DummyClass class], @selector(sendAsynchronousRequest:queue:completionHandler:));
method_exchangeImplementations(original, sub);
            
// test code
 
method_exchangeImplementations(sub, original);

DummyClass内

// for unit test
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler
{
    NSHTTPURLResponse *httpResponse = [[[NSHTTPURLResponse alloc] initWithURL:nil statusCode:200 HTTPVersion:nil headerFields:nil] autorelease];
    handler(httpResponse, nil, nil);
}

helper method

void (^setParameter)(int patternId);
setParameter = ^(int patternId){
    // 設定
};

context(@"when xxx", ^{
    it(@"should xxx", ^{
        setParameter(0);
    });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment