ค้นหาเว็บไซต์

javascript - จะเปลี่ยนการใช้งานของ Jest mock สำหรับการทดสอบบางอย่างได้อย่างไร


ฉันได้สร้างไฟล์ในโฟลเดอร์ test/__mocks__ ของฉัน ซึ่งฉันจำลองโมดูล npm และลิงก์ของไฟล์นี้ถูกเพิ่มไปยังการตั้งค่า jest ของฉัน ทุกอย่างทำงานได้ดี ซึ่งทำให้ฉันสามารถทดสอบได้อย่างเรียบร้อย แต่ตอนนี้สำหรับการทดสอบบางอย่าง ฉันจำเป็นต้องเปลี่ยนค่าที่ส่งกลับจากไฟล์นี้ ฉันจะทำได้อย่างไร?

ฉันพยายามที่จะ unMock บวกกับ setMock ฯลฯ แต่ก็ไม่ได้ผลอะไร

// test/__mocks__/touchId.ts

jest.mock('react-native-touch-id', () => {
  return {
    isSupported: jest.fn(() => Promise.resolve(true)),
    authenticate: jest.fn(() => Promise.resolve(true)),
  };
});

และการทดสอบของฉัน

it('should not navigate to main if touch id return false', async () => {
  jest.setMock('react-native-touch-id', {
    authenticate: jest.fn(() => Promise.resolve(false)),
  });
  const pinCreation = new PinCreationStore();

  const spy = jest.spyOn(NavigationServices, 'navigate');

  spy.mockReset();

  await pinCreation.verifyUser();

  expect(spy).toHaveBeenCalledTimes(0);

  spy.mockRestore();
});

ตรงนี้ฉันยังได้ค่าเป็นจริง ดังนั้นการทดสอบของฉันจึงล่ม

คำตอบ #1

คุณสามารถใช้ jest.mock() ได้โดยไม่ต้องสร้างโฟลเดอร์ __mocks__

ตัวอย่างเช่น:

react-native-touch-id.ts, ฉันจำลองโมดูลนี้เพื่อให้มันเรียบง่าย คุณสามารถแทนที่ด้วยโมดูล npm จริงได้

const touchId = {
  isSupported() {
    return false;
  },
  authenticate() {
    return false;
  }
};
export default touchId;

react-native-touch-id.spec.ts:

import touchId from './react-native-touch-id';

jest.mock('./react-native-touch-id', () => {
  return {
    isSupported: jest.fn(() => Promise.resolve(true)),
    authenticate: jest.fn(() => Promise.resolve(true))
  };
});

describe('react-native-touch-id', () => {
  it('t1', () => {
    expect(touchId.isSupported()).toBeTruthy();
    expect(touchId.authenticate()).toBeTruthy();
  });

  it('t2', () => {
    (touchId.isSupported as jest.MockedFunction<typeof touchId.isSupported>).mockReturnValueOnce(false);
    (touchId.authenticate as jest.MockedFunction<typeof touchId.authenticate>).mockReturnValueOnce(false);
    expect(touchId.isSupported()).toBeFalsy();
    expect(touchId.authenticate()).toBeFalsy();
  });

  it('t3', () => {
    (touchId.isSupported as jest.MockedFunction<typeof touchId.isSupported>).mockReturnValueOnce(true);
    (touchId.authenticate as jest.MockedFunction<typeof touchId.authenticate>).mockReturnValueOnce(false);
    expect(touchId.isSupported()).toBeTruthy();
    expect(touchId.authenticate()).toBeFalsy();
  });
});

อย่างที่คุณเห็น หลังจากที่คุณทำการจำลองโมดูล react-native-touch-id แล้ว คุณจำเป็นต้องนำเข้ามันและจำลองใหม่อีกครั้งเมื่อคุณต้องการให้สองวิธีนี้มีค่าที่แตกต่างกัน ค่าที่จำลองเหล่านี้จะถูกใช้ในโมดูลอื่น ๆ ที่นำเข้าและใช้วิธี isSupported และ authenticate ของโมดูล react-native-touch-id

ผลลัพธ์ของการทดสอบหน่วย:

 PASS  src/stackoverflow/52172531/react-native-touch-id.spec.ts
  react-native-touch-id
    ✓ t1 (5ms)
    ✓ t2 (1ms)
    ✓ t3

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        4.065s