@kintone/rest-api-clientをモックする
副業先でkintoneを利用している。kintoneの機能だけでは賄えない部分は、JSカスタマイズを作成し補っている。そのJSカスタマイズを作成するときに@kintone/rest-api-client
を使うことが多く、単体テスト時はそれをモックしてテストする。今回は備忘録的に@kintone/rest-api-client
をモックする方法について、書く。
インスタンスは外から渡す
モックする方法について書く前に、モックしやすいインタフェースについて書く。
以下のように、関数内でKintoneRestAPIClient
をインスタンス化するとテストしづらい。jest.mock
はクラスでもモックできるが、KintoneRestAPIClient
はclient.record.getRecord(...)
のようにプロパティを挟んでメソッドが生えているのでうまくモックされない。
const someFunction = () => {
const client = new KintoneRestAPIClient();
…
}
なので、インスタンスは外から渡す形に変える。JSカスタマイズのようにブラウザ上でKintoneRestAPIClient
を使う場合、コンストラクタに何も渡す必要がないので、デフォルト引数でインスタンス化したKintoneRestAPIClient
を渡すように書けばよい。そうすると、その関数を利用するときにはKintoneRestAPIClient
を意識する必要はないので、おすすめ。
interface SomeFunctionOptions {
client: KintoneRestAPIClient;
}
const someFunction = ({
client = new KintoneRestAPIClient(),
}: SomeFunctionOptions) => {
…
};
// デフォルト引数でインスタンス化しているので、
// 利用するときにインスタンス化して渡す必要はない
someFunction({});
jest.spyOnでモックする
注:jest前提なので、それ以外のテストフレームワークを使っている場合は同じような関数で読み替えてください
まず、テスト用にKintoneRestAPIClient
をインスタンス化する。jest上でKintoneRestAPIClient
を使う場合、Node環境になるので、baseUrl
・auth
をコンストラクタで渡す必要がある。が、モックすればその辺のパラメタはあまり関係なくなるので、適当な値を渡せばOK。
// jestはNode環境なので、
// コンストラクタに色々渡す必要がある
// baseUrl、authが必須になるが、どうせモックするので適当な値でOK
const client = new KintoneRestAPIClient({
baseUrl: "https://example.cybozu.com/k",
auth: {
username: "hoge",
password: "hoge",
},
});
次に、モックしたいメソッドだけjest.spyOn
でモックする。TypeScript環境の場合、返り値の型など効くようになって、便利だった気がする。直後にbeforeEach
を定義してmockClear
しておくと、mockClear
忘れでテストが不安定になるのを防ぐことができるので、安心。
// モックしたいメソッドだけjest.spyOnする
const getRecordsMock = jest.spyOn(client.record, 'getRecords');
// beforeEachでmockClearする
beforeEach(() => {
getRecordsMock.mockClear();
});
あとは、mockResolvedValue
やmockRejectedValue
で返り値をテストしたい形に書き換えたり、expect(mock).toHaveBeenCalledWith
などで想定通りに呼んでいるかをテストすればよい。
test('…', async () => {
getRecordsMock.mockResolvedValue({
records: [],
totalCount: "0"
});
await someFunction({ client });
expect(getRecordsMock).toHaveBeenCalledWith({ … });
});
おわり
JSカスタマイズでもテスト書いていきの気持ちでやっていこうな。