如何使用Jest模拟对象中的特定函数?

13

我正在使用Jest测试一个React/Reflux应用程序。我在store中有以下函数:

onLoad: function() {
  console.log("ORIGINAL LOAD");
  // http request here
}

我试图模拟它,使其只执行所需操作,而不进行实际的网络操作:

beforeEach(function() {

  // mock out onLoad so instead of making API call the store gets test data
  PostStore.onLoad = jest.genMockFunction().mockImplementation(function () {
    var p1 = new Post(
      "54da7df5119025513400000a",                    // id
      "Test Post",                                   // title
      "Kji6ftLjUqhElgnqOBqMUKxYONpU7nK/cu6jTA==\n",  // owner anonId
      "Test Course 1",                               // course name
      "This is a test!",                             // content
      6,                                             // upvotes
      2,                                             // downvotes
      ["Kji6ftLjUqhElgnqOBqMUKxYONpU7nK/cu6jTA==\n"] // voter anonIds
    );

    this.posts = [p1];
    console.log("mocked function");
  });

  // component initialized here
});

然而,似乎从未创建模拟函数。当我运行测试时,控制台仍会记录ORIGINAL LOAD

如何正确地覆盖对象的方法,以便不是通过ajax调用设置PostStore中的posts数组,而是使用测试数据设置它?


你解决了这个问题吗?我遇到了非常类似的问题,但是我正在使用Jasmine并使用Rewire注入依赖项。我在Reflux GitHub存储库上记录了一个问题:https://github.com/spoike/refluxjs/issues/300 - Simon Adcock
我从未解决过这个问题,但对于Jasmine,我建议使用Sinon来模拟一些东西。 - Hugo
谢谢,结果证明是Rewire的限制,在Reflux的store mixin加载后注入依赖项。最终我选择了inject-loader来使用webpack。 - Simon Adcock
你在测试中使用 PostStore 之前是否已经执行了 var PostStore = require('PostStore')?我认为你需要在 require 语句之后定义 mockImplementation,以确保 jest 自动模拟不会覆盖你的 mockImplementation。 - pherris
我不确定是否正确。我改用仅Rails重写了它。 - Hugo
3个回答

6
我发现了jest mock实例函数。 这里有相关信息。
例如:
import expect from 'expect';

jest.mock('../libs/utils/Master');
import Master from '../libs/utils/Master';

Master.mockImplementation(() => {
  return {
    returnOne: jest.fn().mockReturnValueOnce(1)
  }
})
describe('test Master', function() {
  it('test search', function() {
    let master = new Master();
    expect(master.returnOne()).toEqual(1);
  });
});

5
几乎完成了,你需要做的就是:
const onLoad = jest.fn().mockImplementation(function () {
    var p1 = new Post();//Add your stuff here
    this.posts = [p1];
    console.log("mocked function");
  });
PostStore.onLoad = onLoad.bind(PostStore); //PostStore is your object.

0
你可以获取全局的fetch并用一个模拟对象覆盖它,然后在执行的测试代码中使用这个模拟对象。
const globalFetch = global.fetch;
const mockFetch = jest.fn() as jest.MockedFunction<typeof fetch>;

global.fetch = mockFetch;

afterAll(() => {
  global.fetch = globalFetch;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接