Jest: How to mock one specific method of a class

后端 未结 7 1868
暗喜
暗喜 2020-11-30 23:43

Let\'s suppose I have the following class:

export default class Person {
    constructor(first, last) {
        this.first = first;
        this.last = last         


        
7条回答
  •  抹茶落季
    2020-12-01 00:46

    I've combined both @sesamechicken and @Billy Reilly answers to create a util function that mock (one or more) specific methods of a class, without definitely impacting the class itself.

    /**
    * @CrazySynthax class, a tiny bit updated to be able to easily test the mock.
    */
    class Person {
        constructor(first, last) {
            this.first = first;
            this.last = last;
        }
    
        sayMyName() {
            return this.first + " " + this.last + this.yourGodDamnRight();
        }
    
        yourGodDamnRight() {
            return ", you're god damn right";
        }
    }
    
    /**
     * Return a new class, with some specific methods mocked.
     *
     * We have to create a new class in order to avoid altering the prototype of the class itself, which would
     * most likely impact other tests.
     *
     * @param Klass: The class to mock
     * @param functionNames: A string or a list of functions names to mock.
     * @returns {Class} a new class.
     */
    export function mockSpecificMethods(Klass, functionNames) {
        if (!Array.isArray(functionNames))
            functionNames = [functionNames];
    
        class MockedKlass extends Klass {
        }
    
        const functionNamesLenght = functionNames.length;
        for (let index = 0; index < functionNamesLenght; ++index) {
            let name = functionNames[index];
            MockedKlass.prototype[name] = jest.fn();
        };
    
        return MockedKlass;
    }
    
    /**
    * Making sure it works
    */
    describe('Specific Mocked function', () => {
        it('mocking sayMyName', () => {
            const walter = new (mockSpecificMethods(Person, 'yourGodDamnRight'))('walter', 'white');
    
            walter.yourGodDamnRight.mockReturnValue(", that's correct"); // yourGodDamnRight is now a classic jest mock;
    
            expect(walter.sayMyName()).toBe("walter white, that's correct");
            expect(walter.yourGodDamnRight.mock.calls.length).toBe(1);
    
            // assert that Person is not impacted.
            const saul = new Person('saul', 'goodman');
            expect(saul.sayMyName()).toBe("saul goodman, you're god damn right");
        });
    });
    

提交回复
热议问题