こんばんは。@Esperna です。
背景
前回レガシーなcallbackをasync/awaitで書き直すという記事を書きました。
その際、protoptypeやテストコードについても書きたかったのですが、長くなり過ぎると思ったので別記事にすることにしました。いつもながら車輪の再発明ですが自身の理解を深めるために書いてます。
prototypeでクラスを実現するメソッドの例
- 前回のレガシーなcallbackをasync/awaitで書き直すの関数を簡素化して、クラスメソッド化した例です
- レガシーなprototypeを使って書いてます
asyncTaskOld.js
function AsyncTask() {
console.log(`made at Showa`);
}
AsyncTask.prototype.doAsync = function (callback) {
const TIMEOUT = 10;
const SUCCESS = 1;
setTimeout(() => {
callback(SUCCESS);
}, TIMEOUT);
};
module.exports = new AsyncTask();
classを使ってprototypeを書き直す
下記の通りです。
asyncTask.js
class AsyncTask {
constructor() {
console.log(`made at Heisei`);
}
doAsync(callback) {
const TIMEOUT = 10;
const SUCCESS = 1;
setTimeout(() => {
callback(SUCCESS);
}, TIMEOUT);
}
}
module.exports = new AsyncTask();
個人的な所感ですが、callback版よりもC++やJavaで見慣れたこちらの方がしっくり来ます。
(async/await使いたいので)Promiseで書き直してみる
asyncTaskNew.js
class AsyncTask {
constructor() {
console.log(`made at Reiwa`);
}
doAsync() {
return new Promise((resolve) => {
const TIMEOUT = 10;
const SUCCESS = 1;
setTimeout(() => {
resolve(SUCCESS);
}, TIMEOUT);
});
}
}
module.exports = new AsyncTask();
今回は上述のasyncTaskOld.jsとasyncTaskNew.jsに対してテストコードを書いてみます。
callbackを引数に取る関数に対するテストコード
asyncTaskOld.test.js
const asyncTask = require("./asyncTaskOld");
describe("asyncTask old class test", () => {
const SUCCESS = 1;
test("doAsync shall call callback with SUCCESS", (done) => {
asyncTask.doAsync((result) => {
expect(result).toBe(SUCCESS);
done();
});
});
});
Promiseを返すコードに対するテストコード
asyncTaskNew.test.js
const asyncTask = require("./asyncTaskNew");
describe("asyncTask new class test", () => {
const SUCCESS = 1;
test("doAsync shall return SUCCESS", async () => {
const result = await asyncTask.doAsync();
expect(result).toBe(SUCCESS);
});
});
- テストコードを書くという観点でcallback版とPromise版を比べると
- callback版は引数をマッチャでチェックすることになりネストが深くなります
- Promise版は戻り値をマッチャでチェックすることになりネストが浅いです
- callback版はcallbackの処理をチェックしたい場合はcallback関数内でdoneの呼び出しを書いてあげる必要があります
所感
- テストコードも書きやすくなるのでcallbackではなくPromiseでasync/awaitで書きたいです
- prototypeかclassかはテストコードには影響なさそうですが、C++やJavaを見慣れているのでprototypeは古い仕様だしできれば使いたくないです