ひよっこ。

I want to…

Mockito-Flexを利用してFlexのTDD/BDD環境を構築する(その2)

Posted by hikaruworld : 2011 2月 16

前回の続きになります。

Mockito-Flexの使い方

Java版のMockitoとの差異

基本的にはJava版のMockitoとほぼ同じですが、メソッドなど異なる部分もあります。
Java版のMockitoでは振る舞いのエミュレートの部分では、
when().thenを利用していましたが、mockito-flexの場合は、
given().willを利用する事になります。BDDMockito側を実装しているようですね。

ちょっとつらいのは、現在のmockitoでは複数の振る舞いの定義が出来ていないため、
以下のようなmockを書いても

given(hoge.piyo()).willReturn(“a”);
given(hoge.piyo()).willReturn(“b”);
given(hoge.piyo()).willReturn(“c”);

実行すると、以下のようになってしまいます。

trace(hoge.piyo()) // “a”
trace(hoge.piyo()) // “a”
trace(hoge.piyo()) // “a”

これは、Mockit-flex側でもIssuesとして、
#17 Multiple called given(something).willReturn(something) always returns first setted value
があがっていますが、まだ対応がはいっていないようです。
一応Answerを利用したやり方はあるようですので後述します。

Java版と同様な部分としては、DSL的な記述が可能なように
org.mockito.integrations以下にメソッド群が切り出されています。
Flex版ではグローバルメソッドとして定義されており、
Javaのようなstaticインポートが不要なところは言語的に楽ですね。

なお、これらのメソッドは実際はorg.mockito.Mockitoの
フィールドを呼び出すようになっています。
実際の挙動を確認する場合は、Mockitoの中身を確認すると良いかと思います。

Mockitoによる実装

ここからmockitoによって提供されている機能を確認していきます。
その際テスト対象のクラスが必要になりますので、
以下のクラスを対象にテストを行います。

public class Main
{
    public function Main()
    {
    }
    public function say(name:String):String
    {
        return "Hi " + name;
    }
    public function say(name:String):String
    {
        return "Hi " + name;
    }
    public function sayObj(obj:Object):String
    {
        return "obj is " + name;
    }
    public function check(data:Data):String
    {
        return data.userId;
    }
}
public class Data
{
	public var userId:int;
	public function Data()
	{
	}
}

なお、前回の方法でtargetに格納されている事とします。

Mock化

任意のクラスをMock化して振る舞いを設定する場合の方法です。

givenによる振る舞いの設定

given()を利用する場合は、以下のように記述します。

given(mock化するメソッドとその引数).willReturn(戻り値)

givenの引数にはmock化するメソッド[Mock]対象と、エミュレートしたい引数を設定します。
この引数はmockitoが提供するメソッドを利用して柔軟に設定する事が可能です。
willReturnはgivenによって与えられた条件時に返す値を定義します。
willReturn以外にも、will,willThrowがあります(詳しくは後述)。

引数のmock化

given時に引数をmock化するためのメソッドを見ていきます。

any()

any()は引数にどんな値を与えられても良い事を表します
(当然引数で定義される型の範囲内でですが)。
なお、any()はnull値を許容しますので、値がnullの場合でもmockとして処理されます

/**
 * anyのテストケースを検証_NULLでない場合
 */
[Test]
public function any_is_not_null():void
{
	given(target.say(any())).willReturn("piyo");
	
	var result:String = target.say("abc");
	
	assertThat(result, isA("piyo"));
}
/**
 * anyのテストケースを検証_NULLの場合
 */
[Test]
public function any_is_null():void
{
	given(target.say(any())).willReturn("piyo");

	// nullの場合でもwillReturnの値が返される
	// ちなみにundefでも問題なし
	var result:String = target.say(null);
	
	assertThat(result, isA("piyo"));
}

anyOf(Class)

anyOfも引数にどんな値を与えられても良い事を表します。
anyOfの引数には、対象の型を指定します。
例えばStringの場合は、anyOf(String)のように引数の型を指定します。

/**
 * anyOfのテストケースを検証_NULLでない場合
 */
[Test]
public function anyOf_is_not_null():void
{
	given(target.say(anyOf(String))).willReturn("piyo");

	var result:String = target.say("abc");

	assertThat(result, isA("piyo"));
}

ただし、前述のany()と異なりnull値を許容しません。mock化したメソッドに対して、
nullを引数に呼ばれた場合はArgumentErrorがthrowされます。

ArgumentError: obj cannot be null

havingPropertyOf

havingPropertyOf(property, value)は引数の持つプロパティの値が一致する場合に、
実行することが可能です。

[Test]
public function havingPropertyOf_test():void
{
        // 引数に渡されたプロパティuserIdが12の場合だけmock処理を行うように設定
	given(target.check(havingPropertyOf("userId", 12))).willReturn(22);

	var data:Data = new Data();
	data.userId = 12;
        // この場合にはwillReturnで指定した22が結果としてかえる。
	var result:int = target.check(data);

	verify().that(target.check(data));
	assertThat(result, isA(22));
}

TODO 継承周りとか調査

isItNaN

これはNaNつまり非数である場合にのみMock処理を行うために利用されます

[Test]
public function isItNaN_test():void
{
	given(target.sayObj(isItNaN())).willReturn("NaN value");

	var result:String = target.sayObj(Number.NaN);

	assertThat(result, isA("NaN value"));
}

notNull

そのまんまですね。値がnullでない場合のみMockのエミュレーションが実行されます。

[Test]
public function notNull_test():void
{
	given(target.say(notNull())).willReturn("Value is Null");

	var result:String = target.say("hoge");

	assertThat(result, isA("Value is Null"));
}

と、今回はこの辺で。
次回はverify周りに付いて書きます。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

 
%d人のブロガーが「いいね」をつけました。