我真的非常挣扎于此,所以请非常感谢任何帮助......
我有一个ExternalDependency模块导出一个类。
TestSubject是另一个类模块 当实例化TestSubject时,ExternalDependency实例将在此内部合成。
出于测试目的,我想有选择地在模拟和真实版本的ExternalDependency类之间进行交换。
ExternalDependency.js
module.exports = class ExternalDependency {
constructor () {
this.isMocked = false
}
}
TestSubject.js
const ExternalDependency = require('./ExternalDependency')
module.exports = class TestSubject {
constructor () {
this.externalDependency = new ExternalDependency()
}
isExternalDependencyMocked () {
return this.externalDependency.isMocked
}
}
Test.js
const TestSubject = require('./TestSubject')
const MockedExternalDependency = class ExternalDependency {
constructor () {
this.isMocked = true
}
}
describe ('TestSubject', () => {
it ('will require and instantiate the real ExternalDependency', () => {
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(false)
})
it ('or the mocked one here', () => {
jest.mock('./ExternalDependency', MockedExternalDependency)
// Failing with:
// babel-plugin-jest-hoist: The second argument
// of `jest.mock` must be a function.
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(true)
})
it ('and back to the real', () => {
jest.unmock('./ExternalDependency')
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(false)
})
})
好的,我知道这是错的 但是,我怎样才能实现类似的行为?
答案 0 :(得分:0)
任何正在努力解决这个问题的人...... 刚刚用可能的解决方案醒来。
所以,首先让我们试着了解Jest的工作原理:
// __mock__/ExternalDependency.js
module.exports = 'MOCK'
// ExternalDependency.js
module.exports = 'REAL'
// TestSubject.js
module.exports = require('./ExternalDependency')
// TestSubject.spec.js
const TestSubject = require('./TestSubject')
describe ('TestSubject', () => {
it ('will require the real ExternalDependency', () => {
expect(TestSubject).toEqual('REAL')
})
it ('or the mocked one here', () => {
jest.resetModules()
jest.mock('./ExternalDependency')
// This will work just fine:
// jest.mock('./ExternalDependency', () => {return 'MOCK'})
const TestSubjectMocked = require('./TestSubject')
expect(TestSubjectMocked).toEqual('MOCK')
})
it ('and back to the real', () => {
expect(TestSubject).toEqual('REAL')
})
})
然后解决方案应该很简单:
// __mock__/ExternalDependency.js
module.exports = class ExternalDependency {
constructor () {
this.isMocked = true
}
}
// ExternalDependency.js
module.exports = class ExternalDependency {
constructor () {
this.isMocked = false
}
}
// TestSubject.js
const ExternalDependency = require('./ExternalDependency')
module.exports = class TestSubject {
constructor () {
this.externalDependency = new ExternalDependency()
}
isExternalDependencyMocked () {
return this.externalDependency.isMocked
}
}
// TestSubject.spec.js
const TestSubject = require('./TestSubject')
const mock = () => {
return class ExternalDependency {
constructor () {
this.isMocked = true
}
}
}
describe ('TestSubject', () => {
it ('will require and instantiate the real ExternalDependency', () => {
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(false)
})
it ('or the mocked one here', () => {
jest.resetModules()
jest.mock('./ExternalDependency')
// This works fine too:
// jest.doMock('./ExternalDependency', mock) // you really need doMock here!
const TestSubjectMocked = require('./TestSubject')
const testSubject = new TestSubjectMocked()
expect(testSubject.isExternalDependencyMocked()).toEqual(true)
})
it ('and back to the real', () => {
const testSubject = new TestSubject()
expect(testSubject.isExternalDependencyMocked()).toEqual(false)
})
})
也可以注入类声明:
// TestSubject.js
const ExternalDependency = require('./ExternalDependency')
module.exports = class TestSubject {
constructor () {
this.externalDependency = new ExternalDependency()
}
isExternalDependencyMocked () {
return this.externalDependency.isMocked
}
isSpied() {
this.externalDependency.isSpied()
}
}
// TestSubject.spec.js
const spy = jest.fn()
const mock = (value) => {
return () => {
return class ExternalDependency {
constructor () {
this.isMocked = value
}
isSpied () {
spy()
}
}
}
}
jest.resetModules()
jest.doMock('./ExternalDependency', mock('MyMock'))
const ExternalDependencyMocked = require('./ExternalDependency')
const TestSubjectMocked = require('./TestSubject')
describe ('TestSubject', () => {
it ('tested injected', () => {
const testSubject = new TestSubjectMocked()
expect(testSubject.isExternalDependencyMocked()).toEqual('MyMock')
testSubject.isSpied()
expect(spy).toHaveBeenCalled()
})
})