【问题标题】:How to mock uuid with Jest如何用 Jest 模拟 uuid
【发布时间】:2018-12-25 06:16:51
【问题描述】:

所以在我寻找问题的答案时,我发现了这篇文章:Jest: How to globally mock node-uuid (or any other imported module)

我已经尝试了答案,但我似乎无法正确使用它,因为它给了我一个未定义的错误。我是测试领域的新手,所以请原谅任何重大错误:

这是我的第一个方法

const mockF = jest.mock('uuid'); 

mockF.mockReturnValue('12345789'); 

但它无法识别功能。

“mockF.mockReturnValue 不是函数”以及我尝试过的其他内容。

然后我尝试按照帖子的建议手动模拟,但似乎无法让它工作,你能帮我吗?谢谢

如果有帮助,这是整个测试:

    const faker = require('faker');
    const storageUtils = require('../../storage/utils');
    const utils = require('../utils/generateFile');
    const { generateFileName } = storageUtils;
    const { file } = utils;

    test('should return a valid file name when provided the correct information', () => {
        // ARRANGE
        // create a scope
        const scope = {
            type: 'RECRUITER',
            _id: '987654321',
        };
        // establish what the expected name to be returned is
        const expectedName = 'r_987654321_123456789.png';

        jest.mock('uuid/v4', () => () => '123456789');

        // ACTION
        const received = generateFileName(file, scope);

        // ASSERT
        // expect the returned value to equal our expected one
        expect(received).toBe(expectedName);
    });

【问题讨论】:

  • jest.mock('uuid', () => jest.fn(() => '1')); 适合你吗?
  • 很遗憾没有
  • 我终于解决了!感谢所有的帮助,问题是我在做 jest.mock 和 require 在一个特定的测试而不是一个整体。很抱歉给您添麻烦,再次感谢

标签: javascript jestjs uuid


【解决方案1】:

使用mockImplementation 模拟它。

import uuid from 'uuid/v4';
jest.mock('uuid/v4');

describe('mock uuid', () => {
  it('should return testid }', () => {
    uuid.mockImplementation(() => 'testid');
    ...
  });  
});

确保您import uuid 正确(使用正确的版本参考,例如 v4、v3...)

【讨论】:

  • 我按照示例中提供的方式进行操作,但出现此错误:Property 'mockImplementation' does not exist on type 'v4'.
  • @EA0906 是 TS 错误吗?如果是这样,我在这里找到了解决方案:klzns.github.io/how-to-use-type-script-and-jest-mocks
  • 当我搜索 jasmine 测试时,谷歌不合作,对于那些也登陆这里的人:import * as uuid from 'uuid'; 和你的测试:spyOn(uuid, 'v4').and.returnValue('test-id');
  • @EA0906 对于您的特定问题,您需要使用const uuidVX = require('uuid/vX') 而不是import。然后你可以拨打mockImplementation就可以了。
【解决方案2】:

对于我的情况,我使用了Github issue的答案

jest.mock('uuid/v4', () => {
 let value = 0;
 return () => value++;
});

【讨论】:

  • uuid/v4 返回一个字符串。此外,可以为 mockImplementation 覆盖返回一个 jest.fn()。
【解决方案3】:

假设下面的测试文件,你可以使用 jest.spyOn 调用来模拟出 uuid。

Test.spec.js

import uuid from 'uuid';
import testTarget from './testTarget';

describe('mock uuid', () => {
  it('should return testid }', () => {
    // Arrange
    const anonymousId = 'testid';
    const v1Spy = jest.spyOn(uuid, 'v1').mockReturnValue(anonymousId);

    // Act
    const result = testTarget();

    // Assert
    expect(result).toEqual(anonymousId);
    expect(v1Spy).toHaveBeenCalledTimes(1);
  });  
});

testTarget.js

import uuid from 'uuid';
export default function() {
   return uuid.v1();
}

【讨论】:

  • 请注意,包维护者指出这种导入方法可能已被弃用。
  • ^ 如果是,则需要运行import {v4 } from 'uuid',这意味着您然后模拟该函数
  • 我收到一个错误Cannot spyOn on a primitive value; undefined given :/
【解决方案4】:

这对我有用。在我的例子中,我只想验证函数是否被调用,而不是断言特定的值。

import * as uuid from 'uuid';
jest.mock('uuid');

const uuidSpy = jest.spyOn(uuid, 'v4');

// in a test block
expect(uuidSpy).toHaveBeenCalledTimes(1);

【讨论】:

  • 谢谢。当我使用mockReturnValue 时,这种方法也适用于我:import * as uuid from "uuid"; jest.mock("uuid"); describe("someTest", () => { const uuidSpy = jest.spyOn(uuid, "v4"); uuidSpy.mockReturnValue("some-uuid");
【解决方案5】:

这对我有用

import { v1 as uuidv1 } from 'uuid';

jest.mock('uuid');


... # (somewhere on your test suite)

uuidv1.mockImplementationOnce(() => {
  return 'uuid-123';
});

【讨论】:

    【解决方案6】:

    希望以下两个示例对您有所帮助。

    假设您需要一个 JS 模块,其唯一职责是生成 UUID。 采用 TDD 方法,我们从断言开始,最终发现我们需要一些 UUIDGenerator 和一些方法来返回 UUID:

    it('should generate UUID', () => {
        const myUUID = UUIDGenerator.nextUUID();
        expect(myUUID).toEqual('some-short-v4-uuid-0');
    });
    

    测试,将UUIDGenerator.ts 转化为以下代码:

    import {v4 as uuidv4} from 'uuid';
    const UUIDGenerator = {
      storeUUID(): string {
        return uuidv4();
      }
    };
    export default UUIDGenerator;
    

    现在我们要模拟UUIDGenerator 对uuid 模块的依赖。我们可以通过使用模块工厂参数调用 jest.mock() 来做到这一点,如文档 on jestjs.io 所述。我们现在可以简单地描述 jest 应该如何表现,

    jest.mock('uuid',() => ({
        v4: () => 'some-short-v4-uuid-0'
    }));
    describe('UUIDGenerator', () => { 
        // it block from above
    });
    

    您现在应该看到您通过了测试。

    另一种选择是在项目的某处创建一些uuid.ts

    import {v4 as uuidv4} from 'uuid';
    export default uuidv4;
    

    并将其导入UUIDGenerator.ts:

    import uuidv4 from '../uuid';
    

    在这种情况下,您应该能够模拟您的uuid.ts。我将我的放在父目录中(相对于UUIDGenerator.ts),因此您可以查看不在同一目录中时如何找到它的示例。

    jest.mock('../uuid',
      () => jest.fn(() => '1-234-5678')
    );
    

    【讨论】:

      【解决方案7】:

      如果您将jest.mock('uuid') 放在错误的范围内,您可能会遇到问题。

      这对我来说正确

      import * as uuid from 'uuid';
      jest.mock('uuid');
      describe('utils', () => {
          it('test', () => {
              jest.spyOn(uuid, 'v4').mockReturnValue('mockedValue')
          });
      });
      

      这是不正确的

      import * as uuid from 'uuid';
      describe('utils', () => {
          it('test', () => {
              jest.mock('uuid');
              jest.spyOn(uuid, 'v4').mockReturnValue('mockedValue')
          });
      });
      

      【讨论】:

        【解决方案8】:
        import uuid from 'uuid'
        
        describe('some test', () => {
          it('some test 1', () => {
             const uuidMock = jest.spyOn(uuid, 'v4').mockReturnValue('123434-test-id-dummy');
        
             // expect(uuidMock).toHaveBeenCalledTimes(<number of times called>);
        
          })
        })
        

        【讨论】:

        • 虽然这段代码可以回答这个问题,但最好在不介绍其他代码的情况下解释它是如何解决问题的,以及为什么要使用它。从长远来看,纯代码的答案没有用处。
        【解决方案9】:

        根据这个答案:How do I write test case for a function which uses uuid using jest?

        您可以使用 jest.mock 来模拟 uuid 的导入,如下所示:

        const uuidMock = jest.fn().mockImplementation(() => {
            return 'my-none-unique-uuid';
        });
        jest.mock('uuid', () => {
            return uuidMock;
        });
        

        这种方法的唯一警告是您需要在导入真实文件之前在测试文件中应用模拟

        然后你甚至可以在模拟上断言。

        【讨论】:

          【解决方案10】:

          这对我有用(我正在使用打字稿,如果不是,您可以删除 as blablabla):

          jest.mock('uuid', () => ({
            v4: jest.fn(),
          }));
          const mockUuid = require('uuid') as { v4: jest.Mock<string, []> };
          
          beforeEach(() => {
            mockUuid.v4.mockImplementationOnce(
              () => 'your-mocked-id',
            );
          });
          

          https://github.com/facebook/jest/issues/2172#issuecomment-756921887

          【讨论】:

            【解决方案11】:

            我今天遇到了同样的问题/挑战。 最后我的解决方案是这样的。

            代码(用法):

            import { v4 as uuidv4 } from 'uuid';
            ...
            const uuid = uuidv4();
            ...
            

            测试:

            jest.mock('uuid', () => ({ v4: () => 'adfd01fb-309b-4e1c-9117-44d003f5d7fc' }));
            ...
            describe('Test Foo', () => {
              ...
            });
            

            重要提示: 您需要在第一个“描述”块之前模拟它。

            【讨论】:

              【解决方案12】:

              documentation 里解释得很好,但总的来说你可以:

              const mockF = jest.fn().mockReturnValue('12345789');
              

              import uuid from 'uuid';
              jest.mock('uuid', () => 
                  jest.fn().mockReturnValue('12345789');
              );
              

              【讨论】:

              • 谢谢,但我仍然得到一个未定义的错误:s 其他测试通过,除了这个,所以错误只是在 uuid 上
              • 如果我发布整个测试会有帮助吗?
              猜你喜欢
              • 2021-02-15
              • 2021-03-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-05-29
              • 1970-01-01
              • 1970-01-01
              • 2018-01-26
              相关资源
              最近更新 更多