首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单元测试新手--如何使用Jest测试来测试这段代码?

单元测试新手--如何使用Jest测试来测试这段代码?
EN

Stack Overflow用户
提问于 2019-10-06 22:26:35
回答 1查看 194关注 0票数 0

我是单元测试的新手。我想学习如何正确地使用Jest进行测试,在阅读了关于Udemy的文章、演示和课程之后,我仍然很困惑(尤其是使用Jest mocking)。我应该提一下,我们所有的代码都是在react之外的,所以它似乎更让我困惑。

我已经为我的公司写了一个AB测试,并且已经意识到它应该很容易测试,但我认为我做得不对。看起来我只是在复制我的原始代码来测试,尽管我觉得这个函数是有效的,但在我看来这似乎是错误的。

这是我正在讨论的代码和测试。你们这些更有经验的人怎么才能做到这一点呢?

谢谢!

JS:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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);
      }
    })
  })
})
EN

回答 1

Stack Overflow用户

发布于 2019-10-07 23:07:41

单元测试工作流程非常简单。

  1. 为要测试的方法/函数模拟依赖项及其返回值。为它创建一个隔离的环境。原则是单元测试不应该依赖于任何外部服务,例如发送一个真实的HTTP请求,查询真实的数据库,访问真实的文件system.
  2. Execute你想要测试的方法/函数,测试每个分支(if...elseswitch...case),语句,函数和行。它们是覆盖率的总结,report.
  3. Assert(expect),结果,以及被测试的方法/函数所依赖的方法/函数是否要被调用。为什么?因为我们应该确保代码按照我们期望的

执行

在每个软件arch层中,按照上面的工作流程测试每个方法/函数。

软件架构层是指,例如,数据访问层、模型层、服务层、控制器/路由器层

下面是正确的单元测试:

index.ts

代码语言:javascript
复制
(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

代码语言:javascript
复制
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%覆盖率的单元测试结果:

代码语言:javascript
复制
 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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58258206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档