簡體   English   中英

用Jest嘲笑課程

[英]Mocking classes with Jest

鑒於我有一個類調用函數doStuff如下所示:


const myService = require(`./myService`),
    service = new myService();

exports.doStuff = async (callback) => {
    try {
        const data = await service.doOtherStuff(); //I want to mock this

        return callback(null, data);
    } catch (err) {
        callback(new Error(` > feed failed for ${key}, error: ${err}`));
    }
};

我的測試工作如下:

const myClass = require(`../index`);
jest.mock(`./../myService`, () => {
    return function() {
        return {
            doOtherStuff: () => {
                return 1;
            }
        };
    };
});

describe(`service-tests - index`, () => {
        test(`doStuff and test otherStuff`, async () => {
            const result = await myClass.doStuff((err, data) => {
                return data;
            });

            expect(result).toBe(1);
        });
});

我的服務:

class myService{
    constructor() {
        //Do constructor stuff
    }

    async doOtherStuff() {
        //Do other stuff
    }

這有效,但現在我只是對這個文件進行了模擬,而不是通過測試。 我需要的是讓我的模擬通過測試進行可變的測試,但似乎無法弄清楚它如何與require一起工作。

我試着做jest.mock('./../myService')並在mockImplementation上使用了beforeAll但是這樣可以保持我的函數被模擬為自動模擬看起來,返回undefined

有沒有人曾經這樣做過?

如果你想在類中模擬一個方法,看起來你正在做,我建議你使用jest.spyOn 它很簡單,您可以將返回值模擬為每次測試所需的任何值。

const myClass = require('../index');
const myService = require('../myService');

describe('service-tests - index', () => {

  let doOtherStuffMock;
  beforeAll(() => {
    doOtherStuffMock = jest.spyOn(myService.prototype, 'doOtherStuff');
  });

  it('mocks doOtherStuff one way', async () => {
    doOtherStuffMock.mockResolvedValue('I am a mocked value');
    const result = await myClass.doStuff((err, data) => data);
    expect(result).toBe("I am a mocked value");
  });

  it('mocks doOtherStuff another way', async () => {
    doOtherStuffMock.mockResolvedValue('I am DIFFERENT mocked value');
    const result = await myClass.doStuff((err, data) => data);
    expect(result).toBe('I am DIFFERENT mocked value');
  });
});

更新

我將在這里留下這個答案,因為這兩種方法都有用,它們可以有用......

...但對於這個特殊情況,@丹尼爾是對的,嘲笑原型方法是最簡單的


處理此問題的一種簡單方法是將myService.js模擬為單例...

...然后你可以獲取doOtherStuff的模擬函數並在每次測試時更改它:

const myClass = require(`../index`);

jest.mock(`../myService`, () => {
  const doOtherStuff = jest.fn();  // <= create a mock function for doOtherStuff
  const result = { doOtherStuff };
  return function() { return result; };  // <= always return the same object
});
const doOtherStuff = require('./myService')().doOtherStuff;  // <= get doOtherStuff

describe(`service-tests - index`, () => {

  test(`doStuff and test otherStuff`, async () => {
    doOtherStuff.mockReturnValue(1);  // <= mock it to return something
    const result = await myClass.doStuff((err, data) => data);
    expect(result).toBe(1);  // Success!
  });

  test(`doStuff and test otherStuff`, async () => {
    doOtherStuff.mockReturnValue('something else');  // <= mock it to return something else
    const result = await myClass.doStuff((err, data) => data);
    expect(result).toBe('something else');  // Success!
  });
});

它也可以自動模擬myService.js並使用mockImplementation ...

...但是因為index.js 在運行后立即創建一個myService實例,所以 需要index.js 之前必須確保模擬已經存在:

jest.mock(`../myService`);  // <= auto-mock
const myService = require('../myService');
const doOtherStuff = jest.fn();
myService.mockImplementation(function() { return { doOtherStuff }; });

const myClass = require(`../index`);  // <= now require index

describe(`service-tests - index`, () => {

  test(`doStuff and test otherStuff`, async () => {
    doOtherStuff.mockReturnValue(1);  // <= mock it to return something
    const result = await myClass.doStuff((err, data) => data);
    expect(result).toBe(1);  // Success!
  });

  test(`doStuff and test otherStuff`, async () => {
    doOtherStuff.mockReturnValue('something else');  // <= mock it to return something else
    const result = await myClass.doStuff((err, data) => data);
    expect(result).toBe('something else');  // Success!
  });
});

暫無
暫無

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

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