如果您尝试替换组件的函数/方法,简短的回答是:您不这样做!。
切勿在测试中替换组件的某些部分。在您对组件进行更改后,这些测试用于检查您的组件现在和将来是否会失败。如果您将来引入了重大更改,但测试替换了您引入更改的部分/方法,您的测试将如何知道应用程序已损坏?
测试时需要遵循一些重要原则:
- 请勿修改您的组件以使其通过测试。仅对其进行修改以解决在测试期间发现的实际问题。
- 在测试期间切勿更换组件的部件。您可以(并且应该)做的是模拟任何外部的东西,用功能/模块替换这些部分,执行您期望这些部分在实时环境中执行的操作1。模拟的要点是:
jest.mock('some-module', () => jest.fn().mockImplementation(() => yourMock )).
完整文档here.
模拟需要在您的测试调用 import Something from 'some-module' 之前进行。
- 仅测试组件的输入/输出。不要测试您的组件是如何工作的(也称为内部实现)(这允许您在以后的某个时间重构它而不会破坏测试,只要您的组件仍然按预期为每个提供的输入输出)。
也不要测试外部东西是否有效。您的测试与此无关。外部的东西有自己的测试,通常已经测试过了。这就是您依赖它的原因。
因此,在您的情况下,您希望在测试期间修改 process.env。唯一的问题是 process.env 是全局的,如果您对其进行更改,这些更改将在您的测试结束后持续存在,除非您将所有内容更改回开始测试时的状态。
最重要的是,您必须在每次测试之前调用jest.resetModules(),以清除 jest 缓存(默认情况下,jest 缓存,因此它运行测试更快)。
这是一个如何使用受控process.env 进行测试的示例。这应该消除了替换组件方法的需要:
describe('SomeComponent', () => {
const REAL_ENV = process.env;
beforeEach(() => {
jest.resetModules();
process.env = { ...process.env }; // copy, for your test
});
afterAll(() => {
process.env = REAL_ENV; // restore initial values
});
it('should do stuff depending on process.env', () => {
process.env.FOO = 'bar';
wrapper = shallowMount(/*...*/);
expect(/* wrapper to do stuff...*/)
})
});
使用受控process.env 值进行测试需要在测试内部进行浅层安装,而不是在beforeAll 中进行典型的浅层安装,我通常会创建两个单独的测试套件:一个用于正常测试,一个用于beforeAll 中的浅层安装,另一个对于特殊测试,在浅层安装之前设置环境变量:
describe('SomeComponent - normal tests', () => {
let wrapper;
beforeEach(() => {
wrapper = shallowMount(/*...*/)
});
it('should do stuff', () => {
// component here has already been shallowMounted
})
});
describe('SomeCompoent - process.env tests', () => {
const REAL_ENV = process.env;
let wrapper;
beforeEach(/* ... */); // replace process.env
afterEach(/* ... */); // restore process.env
it('Does stuff with FOO = "bar"', () => {
process.env.FOO = 'bar';
wrapper = shallowMount(/* ... */);
expect(/* wrapper to do stuff when process.env.FOO is 'bar' */)
})
it('Does stuff with FOO = "baz"', () => {
process.env.FOO = 'baz';
wrapper = shallowMount(/* ... */);
expect(/* wrapper to do stuff when process.env.FOO is 'baz' */)
})
})
1 例如,您不想在测试中使用 axios。您不想测试本地计算机是否已连接到 Internet,或者您的应用程序调用的服务器是否实际启动并运行。您想要一个 axios 的替代品,它可以在不进行实际调用的情况下执行 axios 正在做的事情,从而允许您控制返回的响应和错误,从而测试您的组件在从 axios 接收响应/错误时做出正确的调用并按预期运行。