Jest を使用して React Native の node_module 'React Native Keychain' をモックしたいと思います。
続いてドキュメントというフォルダを作成し__mocks__
、その中に というファイルを作成しましたreact-native-keychain.js
。
ファイル内のコードは次のとおりです。
export default jest.mock("react-native-keychain", () => {
const token = "abcdefghijklmnopqrstuvwxyz0123456789";
const credentials = {
username: "session",
password: token
};
return {
setGenericPassword: jest.fn(
(username, password) => new Promise((resolve, reject) => resolve(true)) // eslint-disable-line no-unused-vars
),
getGenericPassword: jest.fn(() => new Promise((resolve, reject) => resolve(credentials))), // eslint-disable-line no-unused-vars
resetGenericPassword: jest.fn(() => new Promise((resolve, reject) => resolve(true))) // eslint-disable-line no-unused-vars
};
});
次に、このライブラリを使用する関数のテストを記述しました。
import * as keyChainFunctions from "react-native-keychain";
import { setToken, getToken, clearToken } from "./secureStorage";
const token = "abcdefghijklmnopqrstuvwxyz0123456789";
describe("set token", () => {
it("saves the token in the keychain", () => {
expect.assertions(1);
return setToken(token).then(res => {
console.log(res);
console.log(keyChainFunctions);
expect(keyChainFunctions.setGenericPassword).toHaveBeenCalledWith("session", token);
});
});
});
問題は、テストが失敗することです。次のエラー メッセージが表示されます:
FAIL app/api/secureStorage/secureStorage.test.js
set token
✕ saves the token in the keychain (42ms)
● set token › saves the token in the keychain
expect(jest.fn())[.not].toHaveBeenCalledWith()
jest.fn() value must be a mock function or spy.
Received: undefined
10 | console.log(res);
11 | console.log(keyChainFunctions);
> 12 | expect(keyChainFunctions.setGenericPassword).toHaveBeenCalledWith("session", token);
| ^
13 | });
14 | });
15 | });
at app/api/secureStorage/secureStorage.test.js:12:52
at tryCallOne (node_modules/promise/lib/core.js:37:12)
at node_modules/promise/lib/core.js:123:15
at flush (node_modules/asap/raw.js:50:29)
● set token › saves the token in the keychain
expect.assertions(1)
Expected one assertion to be called but received zero assertion calls.
6 | describe("set token", () => {
7 | it("saves the token in the keychain", () => {
> 8 | expect.assertions(1);
| ^
9 | return setToken(token).then(res => {
10 | console.log(res);
11 | console.log(keyChainFunctions);
at Object.<anonymous> (app/api/secureStorage/secureStorage.test.js:8:12)
そしてconsole.log()
収穫量:
console.log app/api/secureStorage/secureStorage.test.js:10
true
console.log app/api/secureStorage/secureStorage.test.js:11
{ default:
{ addMatchers: [Function: addMatchers],
advanceTimersByTime: [Function: advanceTimersByTime],
autoMockOff: [Function: disableAutomock],
autoMockOn: [Function: enableAutomock],
clearAllMocks: [Function: clearAllMocks],
clearAllTimers: [Function: clearAllTimers],
deepUnmock: [Function: deepUnmock],
disableAutomock: [Function: disableAutomock],
doMock: [Function: mock],
dontMock: [Function: unmock],
enableAutomock: [Function: enableAutomock],
fn: [Function: bound fn],
genMockFromModule: [Function: genMockFromModule],
isMockFunction: [Function: isMockFunction],
mock: [Function: mock],
requireActual: [Function: bound requireModule],
requireMock: [Function: bound requireMock],
resetAllMocks: [Function: resetAllMocks],
resetModuleRegistry: [Function: resetModules],
resetModules: [Function: resetModules],
restoreAllMocks: [Function: restoreAllMocks],
retryTimes: [Function: retryTimes],
runAllImmediates: [Function: runAllImmediates],
runAllTicks: [Function: runAllTicks],
runAllTimers: [Function: runAllTimers],
runOnlyPendingTimers: [Function: runOnlyPendingTimers],
runTimersToTime: [Function: runTimersToTime],
setMock: [Function: setMock],
setTimeout: [Function: setTimeout],
spyOn: [Function: bound spyOn],
unmock: [Function: unmock],
useFakeTimers: [Function: useFakeTimers],
useRealTimers: [Function: useRealTimers] } }
このことからわかること: 1. モックが機能しているか (true が正しく返されるため)、setGenericPassword
React Native Keychain から実際の関数が呼び出されているかのいずれかです。2. 何らかの理由で、3 つのモック関数ではなくオブジェクトkeychainfunctions
として定義されています。jest.mock
モックが機能する場合、1 と 2 は互いに矛盾しているように感じます。何が間違っているのでしょうか? このモックが機能しないのはなぜですか? これらの奇妙なconsole.log()
s と失敗したテストはどのように説明できますか?
バンセコメントでは、オブジェクトをエクスポートするだけと提案されています。この回避策は機能します。これを正しく行う方法や、何を間違えたのか、まだ興味があります。
const token = "abcdefghijklmnopqrstuvwxyz0123456789";
const credentials = {
username: "session",
password: token
};
export const setGenericPassword = jest.fn(
(username, password) => new Promise((resolve, reject) => resolve(true)) // eslint-disable-line no-unused-vars
);
export const getGenericPassword = jest.fn(
() => new Promise((resolve, reject) => resolve(credentials)) // eslint-disable-line no-unused-vars
);
export const resetGenericPassword = jest.fn(() => new Promise((resolve, reject) => resolve(true))); // eslint-disable-line no-unused-vars
ベストアンサー1
使ってみるのもいいでしょうjest.createMockFromModuleテストで必要なメソッドのみをモックします。(Jest バージョン 26 より前では genMockFromModule と呼ばれていました)
それが役に立てば幸い