我定义了2个JEST模拟。我遇到的问题。第一个模拟无效,而第二个模拟无效。
import Helper from '../../test-helper'
import Storage from '@/storage'
import GuestContext from '@/auth/guest-context'
import UserContext from '@/auth/user-context'
// import LocalStorageGateway from '@/storage/local/local-storage-gateway'
const mockContextUpsert = jest.fn()
jest.mock('@/storage/local/local-storage-gateway', () => {
return jest.fn().mockImplementation((authContext) => {
return {
authContext,
context: {
upsert: mockContextUpsert
}
}
})
})
// import RemoteStorageGateway from '@/storage/remote/remote-storage-gateway'
const mockFetch = jest.fn()
jest.mock('@/storage/remote/remote-storage-gateway', () => {
return jest.fn().mockImplementation((authContext) => {
return {
authContext,
fetch: mockFetch
}
})
})
我尝试过...
mockFetch
代替mockContentUpsert
(当然,将mockFetch
的定义上移之后)。我得到的错误是...
ReferenceError:未定义mockContextUpsert
我无法理解为什么第二个模拟完美运行时第一个模拟不起作用。
这也可以,将模拟变量添加到第二个声明中(没有用,因为它们是不同的类,仅供参考)...
const mockContextUpsert = jest.fn()
const mockFetch = jest.fn()
jest.mock('@/storage/remote/remote-storage-gateway', () => {
return jest.fn().mockImplementation((authContext) => {
return {
authContext: authContext,
fetch: mockFetch,
context: {
upsert: mockContextUpsert
}
}
})
})
这里模拟的类几乎相同。
更新
删除对GuestContext()
的引用[这是附加的复杂性,此后已被删除,并且使该问题试图提出的实际问题感到困惑]
答案 0 :(得分:0)
来自jest documentation的引用:
Jest会将jest.mock调用自动提升到模块顶部(在导入之前)
表示,当您尝试定义模拟mockGuestContext
返回的函数时,尚未定义
您可以做的是创建一个自动模拟
import localStorageGateway from '@/storage/local/local-storage-gateway';
jest.mock('@/storage/local/local-storage-gateway');
// and since localStorageGateway is a function
// jest will automatically create jest.fn() for it
// so you will be able to create authContext
const authContext = new GuestContext();
// and use it within the return value
localStorageGateway.mockReturnValue({
authContext,
context: {
upsert: jest.fn(),
}
})
答案 1 :(得分:0)
我最终解决了这个问题-这里的问题不是模拟本身,而是类被模拟。
LocalStorageGateway
类用于在导入的模块Storage
中创建私有实例,如下所示...
const guestLocal = new LocalStorageGateway(new GuestContext())
此静态上下文使模拟的构造函数在变量定义为Storage
之前执行,这是第一个导入的模块之一。
有几种解决方法...
您可以更改此...
import Helper from '../../test-helper'
import Storage from '@/storage'
import GuestContext from '@/auth/guest-context'
import UserContext from '@/auth/user-context'
(insert mocks here)
到...
const mockContextUpsert = jest.fn()
import Helper from '../../test-helper'
import Storage from '@/storage'
import GuestContext from '@/auth/guest-context'
import UserContext from '@/auth/user-context'
例如(yuk?)。
或者,您也可以将mockContextUpsert
包裹在一个包裹函数中(我之前的回答不是很好-足够好了)->这让我觉得很整洁。
const mockContextUpsert = jest.fn()
jest.mock('@/storage/local/local-storage-gateway', () => {
return jest.fn().mockImplementation((authContext) => {
return {
authContext: authContext,
context: {
upsert: (cxt) => {
mockContextUpsert(cxt)
}
}
}
})
})
我也可以使guestLocal
成为一个函数,但是我真的不想这样做,并且每次我想使用它时都要创建新的网关实例(这就是为什么它首先存在的原因)。如果Storage
是一个类,它将在构造函数中实例化,但是不是,也没有真正的需要。
感谢@Teneff在此方面的投入,他的回答使我的大脑正确地思考了它。 未悬挂变量是关键-它们的工作方式不同-我的理解不正确,那就是任何mockXXXX
都将悬挂在模拟调用之上,但事实并非如此“允许”。