प्रति परीक्षण के आधार पर नकली कार्यान्वयन को कैसे बदलें [जेस्टज]


86

मैं प्रति परीक्षण के आधार पर एक नकली निर्भरता के कार्यान्वयन को डिफ़ॉल्ट मॉक के व्यवहार को बढ़ाकर और अगले परीक्षण के पूरा होने पर मूल कार्यान्वयन पर वापस लौटना चाहूंगा।

संक्षेप में यह वही है जिसे मैं प्राप्त करने की कोशिश कर रहा हूं:

  1. नकली निर्भरता
  2. परिवर्तन / एकल परीक्षण में मॉक क्रियान्वयन का विस्तार करें
  3. जब अगला परीक्षण निष्पादित हो, तो मूल मॉक पर वापस लौटें

मैं वर्तमान में उपयोग कर रहा हूं Jest v21

यहाँ एक विशिष्ट जेस्ट परीक्षण कैसा दिखेगा:

__mocks__/myModule.js

const myMockedModule = jest.genMockFromModule('../myModule');

myMockedModule.a = jest.fn(() => true);
myMockedModule.b = jest.fn(() => true);

export default myMockedModule;

__tests__/myTest.js

import myMockedModule from '../myModule';

// Mock myModule
jest.mock('../myModule');

beforeEach(() => {
  jest.clearAllMocks();
});

describe('MyTest', () => {
  it('should test with default mock', () => {
    myMockedModule.a(); // === true
    myMockedModule.b(); // === true
  });

  it('should override myMockedModule.b mock result (and leave the other methods untouched)', () => {
    // Extend change mock
    myMockedModule.a(); // === true
    myMockedModule.b(); // === 'overridden'
    // Restore mock to original implementation with no side effects
  });

  it('should revert back to default myMockedModule mock', () => {
    myMockedModule.a(); // === true
    myMockedModule.b(); // === true
  });
});

यहाँ मैंने अभी तक कोशिश की है:


1 - mockFn.mockImplementationOnce (fn)

पेशेवरों

  • पहली कॉल के बाद मूल कार्यान्वयन पर वापस लौटता है

विपक्ष

  • यदि परीक्षण bकई बार कॉल करता है तो यह टूट जाता है
  • इसे तब तक मूल कार्यान्वयन में वापस bनहीं किया जाता है जब तक कि इसे बुलाया नहीं जाता (अगले परीक्षण में लीक नहीं होता)

कोड:

it('should override myModule.b mock result (and leave the other methods untouched)', () => {

  myMockedModule.b.mockImplementationOnce(() => 'overridden');

  myModule.a(); // === true
  myModule.b(); // === 'overridden'
});

2 - jest.doMock (मॉड्यूलनाम, कारखाना, विकल्प)

पेशेवरों

  • हर परीक्षण पर स्पष्ट रूप से फिर से मॉक

विपक्ष

  • सभी परीक्षणों के लिए डिफ़ॉल्ट मॉक कार्यान्वयन को परिभाषित नहीं किया जा सकता है
  • प्रत्येक नकली विधि को फिर से घोषित करने के लिए डिफ़ॉल्ट कार्यान्वयन को विस्तारित नहीं कर सकता

कोड:

it('should override myModule.b mock result (and leave the other methods untouched)', () => {

  jest.doMock('../myModule', () => {
    return {
      a: jest.fn(() => true,
      b: jest.fn(() => 'overridden',
    }
  });

  myModule.a(); // === true
  myModule.b(); // === 'overridden'
});

3 - सेटर तरीकों के साथ मैनुअल मॉकिंग (जैसा कि यहां बताया गया है )

पेशेवरों

  • नकली परिणामों पर पूर्ण नियंत्रण

विपक्ष

  • बॉयलरप्लेट कोड का बहुत
  • लंबे समय तक बनाए रखने के लिए मुश्किल है

कोड:

__mocks__/myModule.js

const myMockedModule = jest.genMockFromModule('../myModule');

let a = true;
let b = true;

myMockedModule.a = jest.fn(() => a);
myMockedModule.b = jest.fn(() => b);

myMockedModule.__setA = (value) => { a = value };
myMockedModule.__setB = (value) => { b = value };
myMockedModule.__reset = () => {
  a = true;
  b = true;
};
export default myMockedModule;

__tests__/myTest.js

it('should override myModule.b mock result (and leave the other methods untouched)', () => {
  myModule.__setB('overridden');

  myModule.a(); // === true
  myModule.b(); // === 'overridden'

  myModule.__reset();
});

4 - jest.spyOn (ऑब्जेक्ट, मेथडनाम)

विपक्ष

  • मैं mockImplementationमूल नकली रिटर्न मान पर वापस नहीं लौट सकता , इसलिए अगले परीक्षणों को प्रभावित करता है

कोड:

beforeEach(() => {
  jest.clearAllMocks();
  jest.restoreAllMocks();
});

// Mock myModule
jest.mock('../myModule');

it('should override myModule.b mock result (and leave the other methods untouched)', () => {

  const spy = jest.spyOn(myMockedModule, 'b').mockImplementation(() => 'overridden');

  myMockedModule.a(); // === true
  myMockedModule.b(); // === 'overridden'

  // How to get back to original mocked value?
});

अच्छा लगा। लेकिन आप '@ प्राइवेट-रेपो / मॉड्यूल' जैसे एनपीएम मॉड्यूल के लिए विकल्प 2 कैसे करते हैं? मेरे द्वारा देखे गए अधिकांश उदाहरणों में सापेक्ष पथ हैं? क्या यह स्थापित मॉड्यूल के लिए भी काम करता है?
mrbinky3000

जवाबों:


47

टेस्ट लिखने के लिए एक अच्छा पैटर्न एक सेटअप फैक्ट्री फ़ंक्शन बनाना है जो आपको वर्तमान मॉड्यूल के परीक्षण के लिए आवश्यक डेटा लौटाता है।

नीचे आपके दूसरे उदाहरण के बाद कुछ नमूना कोड दिए गए हैं, हालांकि पुन: प्रयोज्य तरीके से डिफ़ॉल्ट और ओवरराइड मानों के प्रावधान की अनुमति देता है।

const spyReturns = returnValue => jest.fn(() => returnValue);

describe("scenario", () => {
  const setup = (mockOverrides) => {
    const mockedFunctions =  {
      a: spyReturns(true),
      b: spyReturns(true),
      ...mockOverrides
    }
    return {
      mockedModule: jest.doMock('../myModule', () => mockedFunctions)
    }
  }

  it("should return true for module a", () => {
    const { mockedModule } = setup();
    expect(mockedModule.a()).toEqual(true)
  });

  it("should return override for module a", () => {
    const EXPECTED_VALUE = "override"
    const { mockedModule } = setup({ a: spyReturns(EXPECTED_VALUE)});
    expect(mockedModule.a()).toEqual(EXPECTED_VALUE)
  });
});

40

वेनिला जेएस

MockFn.mockImplementation (fn) का उपयोग करें ।

import { funcToMock } from './somewhere';
jest.mock('./somewhere');

beforeEach(() => {
  funcToMock.mockImplementation(() => { /* default implementation */ });
});

test('case that needs a different implementation of funcToMock', () => {
  funcToMock.mockImplementation(() => { /* implementation specific to this test */ });
  // ...
});

टाइपप्रति

संदेश को रोकने के लिए mockImplementation funcToMock की संपत्ति नहीं है , आपको ऊपर से शीर्ष पंक्ति को बदलकर, प्रकार निर्दिष्ट करना होगा:

import { (funcToMock as jest.Mock) } from './somewhere';

इस मुद्दे को संबोधित करने वाला एक प्रश्न यहां पाया जा सकता है: जेस्ट टाइपस्क्रिप्ट प्रॉपर्टी मॉक प्रकार पर मौजूद नहीं है


21

पार्टी के लिए थोड़ा देर से, लेकिन अगर किसी और के साथ इस मुद्दे पर है।

हम प्रतिक्रिया-मूल विकास के लिए टाइपस्क्रिप्ट, ईएस 6 और बेबल का उपयोग करते हैं।

हम आम तौर पर रूट __mocks__निर्देशिका में बाहरी एनपीएम मॉड्यूल का मजाक उड़ाते हैं ।

मैं मॉड्यूल के एक विशिष्ट कार्य को ओवरस की प्रामाणिक कक्षा में एक विशिष्ट परीक्षण के लिए प्रवर्धित करना चाहता था।

    import { Auth } from 'aws-amplify';
    import GetJwtToken from './GetJwtToken';
    ...
    it('When idToken should return "123"', async () => {
      const spy = jest.spyOn(Auth, 'currentSession').mockImplementation(() => ({
        getIdToken: () => ({
          getJwtToken: () => '123',
        }),
      }));

      const result = await GetJwtToken();
      expect(result).toBe('123');
      spy.mockRestore();
    });

Gist: https://gist.github.com/thomashagstrom/e5bffe6c3e3acec592201b6892226af2

ट्यूटोरियल: https://medium.com/p/b4ac52a005d#19c5

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.