首页 > 解决方案 > 如何在测试期间模拟 Sails.js / Waterline 模型

问题描述

我正在尝试使用 sinon.js 模拟 Sails 模型。当我测试我正在使用的部分来检索新创建的行时,我遇到了.fetch()问题Model.create()

这是我要模拟的代码:

...
let newObject = await Object.create(newObjectData).fetch();
...

这是我的测试代码

const sinon = require('sinon');
const supertest = require('supertest');

describe('Object create action', function() {
  let sandbox;
  beforeEach(function() {
    sandbox = sinon.createSandbox();
  });
  afterEach(function() {
    sandbox.restore();
  });

  it('should create Object', function(done) {

    const objectCreateStub = sandbox.stub(Object, 'create').callsFake(async function(data) {
      console.log(data);
      return {
        key: 'value'
      };
    });
    supertest(sails.hooks.http.app)
      .post(`/objects`)
      .send({
        key: 'value'
      })
      .expect(200)
      .end(done);
  });
});

我不知道Object.create伪造的函数应该返回什么.fetch才能不抛出错误。所以,正如预期的那样,我收到了这个错误:

TypeError: Object.create(...).fetch is not a function

什么样的对象会Model.create()返回,所以我也可以模拟它?是否有使用 Sails 和 Waterline 进行测试的最佳实践?

谢谢!

标签: testingsails.jswaterlinesails-postgresql

解决方案


我想通了,但我仍然无法说出它是如何工作的以及应该如何测试它(正确地)

我的代码的问题是:只有链中调用的最后一个函数是“异步”的,所以在模拟这个时,只能fetch是异步的

这是我的测试代码

const objectCreateStub = sandbox.stub(Object, 'create').callsFake(function (data) { // Notice here fake function IS NOT async
  console.log(data
  return {
    fetch: async () => {  // Here we "mock" the fetch function and it MUST be async !
      return newTest
    }
  };
});

如果你不使用fetch,模拟应该是这样的:

const objectCreateStub = sandbox.stub(Object, 'create').callsFake(async function(data) {  // here fake function MUST BE async
  console.log(data)
});

如果您了解 Waterline 查询的工作原理以及为什么我们应该使用此解决方法,请发布另一个答案,因为我的代码有效,但我仍有很多问题:/


推荐阅读