mochaのテスト実行時、VSCodeでES6のコードに埋め込んだブレークポイントを有効にしたい。
結構設定が大変でした。。
やり方を乗せておきます。
インストールされている環境
mocha babel-register
babel-registerを有効にしないで、そのままmochaコマンドを実行すると
import文などのES6記述で構文エラーが発生します。
上記自体はpackage.jsonのscriptに
babel-registerでコンパイルしてあげればOKですが
例:
"test": "NODE_ENV=test mocha --recursive --compilers js:babel-register test/*",
これをVSCode上で適用したい。。と思ったのが背景でした。
設定は下記のようにしました。
//■launch.json { "version" : "0.2.0", "configurations" : [ { "name" : "Run mocha", "program" : "${workspaceRoot}/node_modules/mocha/bin/_mocha", "request" : "launch", "args" : [ "--compilers", "js:babel-core/register", "--recursive", "--debug-brk", "test/**/*.js" ], "cwd" : "${workspaceRoot}", "env" : { "NODE_ENV" : "development" }, "protocol" : "inspector", "runtimeExecutable" : null, "stopOnEntry" : false, "type" : "node" } ] }
nameはいわずがなでprogramにmochaのファイルを読み込ませます。
argsにmochaに渡す引数オプションを渡しています。
"--compilers","js:babel-core/register"とそれぞれargsに個別に渡していいのね。。
って事をしらなくて小一時間悩みましたw
続いてpackeage.jsonのscriptsの中に下記を追加
"test-debug": "NODE_ENV=test mocha --recursive --debug-brk --compilers js:babel-register test/**/*.js"
今回はtest-debugと命名しましたが何でもいいと思います。(npmコマンドに存在しなければ)
ですが、testコマンドと違って--debug-brkを入れないとコマンドが終了してしまいブレークポイントにヒットしません。
↑これがなくても動きました。。launch.jsonに設定するだけで大丈夫のようです。
これで設定は完了!
まずはターミナルで下記コマンドを実行します。
npm run test-debug
今回test-debugと命名したので、runをつけなければ動きません。
npm上でエイリアスできないものはrunをつけないと動かない?というイメージです。
(ちなみにtstやtもtestコマンドとしてエイリアスされるので、被らないようにしなければいけないっぽい)
詳しく読んでないので文献を載せておきます。意味が違ったらすみません。
test | npm Documentation
run-script | npm Documentation
次にtestディレクトリ配下のjsファイルにブレークポイントを設置して・・・
VSCode上のデバック項目を確認
launch.jsonで命名したRun mochaが反映されています。
再生アイコンを押して実行!
ちゃんとES6上のコードが反映されています。
一件落着!
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("こんにちは"); //実装部分はないが呼び出される } } }
出力結果:さようなら