同一个文件中的tests是串行执行的
用toHaveBeenCalledTimes断言调用构造函数的次数
//hookSaga.js
...
const userStorage = new UserStorage()
export function* loginHookSaga() {}
export function* logoutHookSaga() {}
export function* restoreHookSaga() {}
...
//hookSaga.test.js
import UserStorage from 'src/util/UserStorage'
jest.mock('src/util/UserStorage')
//这里mock了userSaga是为了避免hookSaga里面import真正地userSaga的时候,会再次创建UserStorage
jest.mock('src/redux/sagas/userSaga')
describe("test", () => {
afterEach(() => {
//这里会直接把之前new的UserStorage清理掉,并且下一个test case里require时也不会重新new一个。
UserStorage.mockClear()
})
test("test1", () => {
const {loginHookSaga} = require('./hookSaga')
//调用UserStorage构造方法的次数
expect(UserStorage).toHaveBeenCalledTimes(1)
})
test("test2", () => {
const {logoutHookSaga} = require('./hookSaga')
expect(UserStorage).toHaveBeenCalledTimes(1)
})
test("test3", () => {
const {restoreHookSaga} = require('./hookSaga')
expect(UserStorage).toHaveBeenCalledTimes(1)
})
})
使用require只会把其中的 new UserStorage() 执行一遍。所以这三个测试只有test1能通过,因为afterEach
执行了Clear all instances and calls to constructor and all methods。
如果需要test2、test3能通过,需要手动new const userStorage = new UserStorage()
。
如何mock storage.loadInfo
的返回值
有很多地方会用到如const userName = yield call(userStorage.loadInfo, 'name')
操作。此时就需要mock一下userStorage.loadInfo
方法的返回值。有以下思路:
- 首先要成功mock一个UserStorage.
jest.mock('src/util/UserStorage')
- 然后在test case中获取UserStorage的实例
const userStorage = UserStorage.mock.instances[0]
- 然后mock该实例userStorage的方法的返回值,如
const userStorage = UserStorage.mock.instances[0]
userStorage.loadUserInfo = jest.fn().mockImplementation(() => loginCache)
userStorage.loadInfo = jest
.fn()
.mockImplementationOnce(() => userId)
.mockImplementationOnce(() => userName)
.mockImplementationOnce(() => institution)
.mockImplementationOnce(() => location)
.mockImplementationOnce(() => company)
Ref: