簡體   English   中英

如何用 Jest 模擬 uuid

[英]How to mock uuid with Jest

所以在尋找問題的答案時,我發現了這篇文章: 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', () => ({ v4: () => '123456789' }));

順便說一句,使用變量而不是'123456789'會破壞它。

這應該在我們有導入的地方被模擬,它不需要您在規范文件中明確導入uuid

使用mockImplementation模擬它。

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

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

確保正確import uuid (使用正確的版本參考,例如 v4、v3...)

假設有以下測試文件,您可以使用 jest.spyOn 調用來模擬 uuid。

測試規范.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);
  });  
});

測試目標.js

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

這對我有用。 就我而言,我只想驗證函數是否被調用,而不是對特定值進行斷言。

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

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

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

對於我的情況,我使用了這個Github 問題的答案

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

希望下面的兩個例子會有所幫助。

假設您需要一個 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 模塊的依賴。 我們可以通過使用 jestjs.io 上記錄的模塊工廠參數調用 jest.mock() 來做到這一點 我們現在可以簡單地描述玩笑應該如何表現,

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')
);

這對我有用

import { v1 as uuidv1 } from 'uuid';

jest.mock('uuid');


... # (somewhere on your test suite)

uuidv1.mockImplementationOnce(() => {
  return 'uuid-123';
});
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>);

  })
})

根據這個答案: 如何為使用 jest 使用 uuid 的函數編寫測試用例?

您可以使用 jest.mock 來模擬 uuid 的導入,如下所示:

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

該方法的唯一警告是您需要在導入真實文件之前在測試文件中應用模擬

然后你甚至可以在模擬上斷言。

這對我有用(我正在使用打字稿,如果不是,您可以刪除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

如果您將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')
    });
});

我今天遇到了同樣的問題/挑戰。 最后我的解決方案看起來像這樣。

代碼(用法):

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

測試:

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

重要提示:您需要在第一個“描述”塊之前模擬它。

我正在使用打字稿,這對我有用。

jest.mock('uuid', () => {
  return {
    __esModule: true,
    v4: jest.fn().mockReturnValue('9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'),
  };
});

describe("Test suit", () => {
// your tests
});

這確實有效

jest.mock('uuid', () => {
  const originalModule = jest.requireActual('uuid');
  return {
    __esModule: true,
    ...originalModule,
    v4: jest.fn(() => '634b59eb-dc11-48f0-ad46-ca2d85ef2a9d')
  };
});

但是,您必須在測試文件之上定義它。 不在beforeAll()中。

有關更多信息,請參閱jest 中的模擬函數

在我使用uuid npm 包的v4方法強行使用之前,上面的任何東西都不起作用:

import { v4 } from 'uuid'

jest.mock('uuid', () => ({
    v4: jest.fn(),
}))

beforeEach(() => {
  ;(v4 as jest.Mock).mockReturnValue('mock-uuid-1234')
}

afterEach(() => {
  jest.clearAllMocks()
}

希望這可以幫助。

其他答案將為您解決問題,但我更喜歡將模擬值設置為變量,這樣您就不會在整個測試中復制/粘貼硬編碼字符串。

const mockUUID = 'mocked-uuid'
jest.mock('uuid', () => ({ v4: () => mockUUID }))

需要注意的重要一點是,您必須以mock開頭的變量名才能正常工作。 更多信息可以在這里找到: https://jestjs.io/docs/es6-class-mocks#calling-jestmock-with-the-module-factory-parameter

文檔中對此進行了很好的解釋,但通常您可以:

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

要么

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM