びぼーろくっ!

誰かに見せるわけでもないけど、備忘録として。。

ES6の記述でmocha + sinon.jsを使ったスタブ化を実施したのでメモ。。

いやー、大変だった。
そもそもES6の記述方法に慣れていないというのもあるけど、
ドキュメントやexsampleをあまり見ないで実施したので今度から見るようにしようw

処理の内容
./data/person.jsonの中にある大量の人物データからidに一致する人物を抽出します。
ただし元データのjsonファイルに一致するIDが存在しない場合、
当然getPersonNameAddGreeting()でもコケます。
今回はgetPersonsの戻りや処理をスタブ化します。
スタブ化されるため、getPersonsの中の処理は走りません。
そのためgetPersonsの中のconsole.log()も出力されません。


test.js

    //必要なモジュールをインクルード
    //アサーションはpower-assertを使用しています。
    import mocha from 'mocha';
    import assert from 'power-assert';
    import sinon from 'sinon';

    //テスト対象をインクルード
    function requireTestTarget(){
      return require('../testTarget/target');
    }

    // ダミーデータを作成します
    function createDummyData () {
      return {
        "id": "b2223",
        "firstName" : "名無しの権兵衛"
      };
    }

    // 対象のメソッドをスタブ化します。
    function modifyStub(stubTarget,methodName){
      return sinon.stub(stubTarget,methodName);
    }

    //テスト実行&検証
    function ExecuteAndVerifycation(expected) {

      //下記メソッドをStub化する(引数には存在しないデータを渡す)
      let person = target.getPersons('aaaaaaaaaaaaaaaaaaaa');

      // テストの実行
      let result = target.getPersonNameAddGreeting(person);
      
      //検証
      assert(result === expected, 'personNameが一致すること');
    }

    let target;

    //mochaにてテストを実行します。
    describe('sinonTest',() => {
      target = requireTestTarget();
      let stubGetPerson = modifyStub(target, 'getPersons');

      it('testCase1_success', () => {
        stubGetPerson.returns(createDummyData());
        ExecuteAndVerifycation('こんにちは。名無しの権兵衛さん');
      });

      it('testCase2_fail',() => {
        stubGetPerson.returns({"id":"fail","firstName":undefined});
        ExecuteAndVerifycation('そんなひとは存在しない!出て行ってくれ!');
      });
    });

target.js(テスト対象ファイル)

    import personData from './data/person.json';

    exports.getPersons = (id) => {
      let returnValue = '';
      personData.forEach((val) => {
        if (id === val.id) returnValue = val;
      });
      //下記のコンソールが流れていたらStub化していない(処理が走ってる為アウト)
      console.log(`ここが通ってたらStub化していない!戻り値が${returnValue}`);
      return returnValue;
    };

    exports.getPersonNameAddGreeting = (person) => {
      if (person.firstName !== undefined) {
        return `こんにちは。${person.firstName}さん`;
      }
      // personに名前がない場合、説教される。
      return 'そんなひとは存在しない!出て行ってくれ!';
    };

Node.jsは奥が深いですネ。。。

C#でのMOCKの基本的な使い方

今MOCKを中心としてソースコードを記載しているのですが
忘れないように基本的な部分を書いてみました。
参考にならないかもしれませんが、備忘録として。

参考例:

//MoqをNUGETからDL後、下記を定義
using Moq;

//定義
var mock = new Mock</*インターフェース*/>();
//定義したMockの関数を設定
//ImplementMethod //ごまかしたい関数
// IsAny Matches any value of the given TValue type
mock.Setup( x=> x.ImplementMethod(It.IsAny</*型*/>()))
	.Returns/*非同期の場合Asyncを追加*/(  /*戻したい型やobject*/);

実装全て

using Moq;

namespace Verification
{
    //実装部分がまだなInterfaceクラス
    public interface IUnfinishedClass
    {
        string ImplementMethod(string num);
    }
    //IUnfinishedClassの処理が必要なメソッド
    public class Call
    {
        public string CallImplement()
        {
            var mock = new Mock<IUnfinishedClass>(); //Mockを定義
            //InterfaceのImplementMethodをラムダで定義。
            //IsAnyを使用するといつでも呼び出せる
            mock.Setup(x => x.ImplementMethod(It.IsAny<string>()))
                .Returns("さようなら");
            var mockMethod = mock.Object; //Setupしたobjectを定義,interfaceが返る
            
            return mockMethod.ImplementMethod("こんにちは"); //実装部分はないが呼び出される
        }
    }
}
出力結果:さようなら