Chai 间谍和异步调用不会调用一次

Chai spies and async calls not call once

我正在构建一个应用程序,我需要在其中测试快速回调解决方案中的一些回调行为。

实际上,它看起来像:

const callbackRender = (httpResponse, response) => {
  console.log(httpResponse) // logs the good httpResponse object
  if (httpResponse.content.content) response.send(httpResponse.content.content)
  else response.render(httpResponse.content.page)
}

const callback = (injector, route) => {
  return (request, response) => {
    const ctrl = injector.get(route.controller)
    const result = ctrl[route.controllerMethod](new HttpRequest())
    if (result.then) {
      return result.then(res => callbackRender(res, response))
    } else {
      callbackRender(result, response)
    }
  }
}

两个失败的测试看起来像:

it('should call the callback render method when httpResponse is a promise', (done) => {
      const mock = sinon.mock(injector)
      const ctrl = new UserControllerMock()
      const routes = routeParser.parseRoutes()
      mock.expects('get').returns(ctrl)
      const spy = chai.spy.on(callbackRender)
      callback(injector, routes[3])(request, response).then((res) => {
        expect(spy).to.have.been.called.once
        mock.verify()
        mock.restore()
        done()
      })
    })

    it('should call the callback render method when httpResponse is not a promise', () => {
      const mock = sinon.mock(injector)
      const ctrl = new UserControllerMock()
      const routes = routeParser.parseRoutes()
      mock.expects('get').returns(ctrl)
      const spy = chai.spy.on(callbackRender)
      callback(injector, routes[1])(request, response)
      expect(spy).to.have.been.called.once
      mock.verify()
      mock.restore()
    })

chai-spies 似乎无法检测到在回调方法中调用了我的 callbackRender 函数。

事实是,当我记录我的方法时,每次我需要它时都会在其中传递。

有人有想法吗?

编辑:beforeEach 中的请求/响应定义

 beforeEach(() => {
    request = {
      body: {},
      params: {},
      query: {}
    }
    response = {
      send: () => {
      },
      render: () => {
      }
    }});

Spies/stubs/mocks 只有在可以 替换 原始函数(带有包装版本)的情况下才能工作,如果 or得到显式传递(在您的代码中不是这种情况)。

在你的例子中,callbackRender 没有被替换(它不能被替换,因为 const 但也因为它没有 "parent" 对象可以被替换替换),因此任何调用它的代码(如 callback)将调用原始函数,而不是间谍。

解决方案取决于代码的结构。

如果 callbackcallbackRender 位于一个单独的模块中,您可以使用 rewire 到 "replace" callbackRender 与间谍.

但是,需要注意的是 rewire 也不能替换 const variables,因此您的代码必须更改。