我是单元测试的新手。我想学习如何正确地使用Jest进行测试,在阅读了关于Udemy的文章、演示和课程之后,我仍然很困惑(尤其是使用Jest mocking)。我应该提一下,我们所有的代码都是在react之外的,所以它似乎更让我困惑。
我已经为我的公司写了一个AB测试,并且已经意识到它应该很容易测试,但我认为我做得不对。看起来我只是在复制我的原始代码来测试,尽管我觉得这个函数是有效的,但在我看来这似乎是错误的。
这是我正在讨论的代码和测试。你们这些更有经验的人怎么才能做到这一点呢?
谢谢!
JS:
let ABTestValue = 30;
ABTest();
export function ABTest() {
const roll = Math.floor(Math.random() * 100);
if (debugMode) {
console.log('TimedRefresh - AB Test Issue-831 (90 and above get their refresh time changed) randomized value = ', roll);
}
const ABTestMappings = [
{
roll: 90,
ABTestValue: 40
},
{
roll: 91,
ABTestValue: 40
},
{
roll: 92,
ABTestValue: 50
},
{
roll: 93,
ABTestValue: 50
},
{
roll: 94,
ABTestValue: 60
},
{
roll: 95,
ABTestValue: 60
},
{
roll: 96,
ABTestValue: 70
},
{
roll: 97,
ABTestValue: 70
},
{
roll: 98,
ABTestValue: 80
},
{
roll: 99,
ABTestValue: 80
}
];
if (roll > 89 && roll < 100) {
ABTestValue = ABTestMappings.filter((a) => a.roll === roll)[0].ABTestValue;
}
window.rg_version = `time${ABTestValue}`;
if (debugMode) {
console.log('TimedRefresh - ABTestValue - change in refresh time in seconds (30 is default) - ', ABTestValue);
}
}test.js:
import { ABTest } from './index';
describe('ABTEST test', () => {
it('ABTest function', () => {
expect(ABTest).toBeDefined();
})
describe('test different rolls', () => {
const ABTestMappings = [
{
roll: 90,
ABTestValue: 40
},
{
roll: 91,
ABTestValue: 40
},
{
roll: 92,
ABTestValue: 50
},
{
roll: 93,
ABTestValue: 50
},
{
roll: 94,
ABTestValue: 60
},
{
roll: 95,
ABTestValue: 60
},
{
roll: 96,
ABTestValue: 70
},
{
roll: 97,
ABTestValue: 70
},
{
roll: 98,
ABTestValue: 80
},
{
roll: 99,
ABTestValue: 80
}
];
const roll = 92;
const roll2 = 95;
const roll3 = 99;
const roll4 = 80;
let ABTestValue = 30;
let ABTestValue2 = 30;
let ABTestValue3 = 30;
let ABTestValue4 = 30;
if (roll > 89 && roll < 100) {
ABTestValue = ABTestMappings.filter((a) => a.roll === roll)[0].ABTestValue;
}
if (roll2 > 89 && roll2 < 100) {
ABTestValue2 = ABTestMappings.filter((a) => a.roll === roll2)[0].ABTestValue;
}
if (roll3 > 89 && roll3 < 100) {
ABTestValue3 = ABTestMappings.filter((a) => a.roll === roll3)[0].ABTestValue;
}
if (roll4 > 89 && roll4 < 100) {
ABTestValue4 = ABTestMappings.filter((a) => a.roll === roll4)[0].ABTestValue;
}
it('if roll is 92', () => {
if (roll) {
expect(ABTestValue).toEqual(50);
}
})
it('if roll is 95', () => {
if (roll2) {
expect(ABTestValue2).toEqual(60);
}
})
it('if roll is 99', () => {
if (roll3) {
expect(ABTestValue3).toEqual(80);
}
})
it('if roll is less than 90', () => {
if (roll4) {
expect(ABTestValue4).toEqual(30);
}
})
})
})发布于 2019-10-07 23:07:41
单元测试工作流程非常简单。
if...else,switch...case),语句,函数和行。它们是覆盖率的总结,report.expect),结果,以及被测试的方法/函数所依赖的方法/函数是否要被调用。为什么?因为我们应该确保代码按照我们期望的执行
在每个软件arch层中,按照上面的工作流程测试每个方法/函数。
软件架构层是指,例如,数据访问层、模型层、服务层、控制器/路由器层
下面是正确的单元测试:
index.ts
(window as any).rg_version = '';
export function ABTest(debugMode = false) {
const roll = Math.floor(Math.random() * 100);
let ABTestValue = 30;
if (debugMode) {
console.log(
'TimedRefresh - AB Test Issue-831 (90 and above get their refresh time changed) randomized value = ',
roll
);
}
const ABTestMappings = [
{
roll: 90,
ABTestValue: 40
},
{
roll: 91,
ABTestValue: 40
},
{
roll: 92,
ABTestValue: 50
},
{
roll: 93,
ABTestValue: 50
},
{
roll: 94,
ABTestValue: 60
},
{
roll: 95,
ABTestValue: 60
},
{
roll: 96,
ABTestValue: 70
},
{
roll: 97,
ABTestValue: 70
},
{
roll: 98,
ABTestValue: 80
},
{
roll: 99,
ABTestValue: 80
}
];
if (roll > 89 && roll < 100) {
ABTestValue = ABTestMappings.filter(a => a.roll === roll)[0].ABTestValue;
}
(window as any).rg_version = `time${ABTestValue}`;
if (debugMode) {
console.log('TimedRefresh - ABTestValue - change in refresh time in seconds (30 is default) - ', ABTestValue);
}
}index.spec.ts
import { ABTest } from './';
describe('ABTest', () => {
afterEach(() => {
jest.restoreAllMocks();
(window as any).rg_version = '';
});
it('should filter and get the correct value', () => {
const floorSpy = jest.spyOn(Math, 'floor').mockReturnValueOnce(90);
const logSpy = jest.spyOn(console, 'log');
ABTest();
expect((window as any).rg_version).toBe('time40');
expect(floorSpy).toBeCalledTimes(1);
expect(logSpy).toBeCalledTimes(0);
});
it('should get default value', () => {
const floorSpy = jest.spyOn(Math, 'floor').mockReturnValueOnce(80);
const logSpy = jest.spyOn(console, 'log');
ABTest(true);
expect((window as any).rg_version).toBe('time30');
expect(floorSpy).toBeCalledTimes(1);
expect(logSpy.mock.calls[0]).toEqual([
'TimedRefresh - AB Test Issue-831 (90 and above get their refresh time changed) randomized value = ',
80
]);
expect(logSpy.mock.calls[1]).toEqual([
'TimedRefresh - ABTestValue - change in refresh time in seconds (30 is default) - ',
30
]);
});
});100%覆盖率的单元测试结果:
PASS src/stackoverflow/58258206/index.spec.ts
ABTest
✓ should filter and get the correct value (8ms)
✓ should get default value (6ms)
console.log node_modules/jest-mock/build/index.js:860
TimedRefresh - AB Test Issue-831 (90 and above get their refresh time changed) randomized value = 80
console.log node_modules/jest-mock/build/index.js:860
TimedRefresh - ABTestValue - change in refresh time in seconds (30 is default) - 30
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 2.814s, estimated 6s源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58258206
https://stackoverflow.com/questions/58258206
复制相似问题