【问题标题】:Test that a function is called in a promise resolution测试一个函数在 promise 解析中被调用
【发布时间】:2016-10-07 06:57:42
【问题描述】:

我正在构建一个应用程序,我需要在其中测试回调函数是否已在承诺解析中被调用。

其实我有以下代码:

const callbackRender = (httpResponse, response) => {
  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) {
      result.then(res => {
        console.log('hey I m in !')
        callbackRender(res, response)
      })
    } else {
      callbackRender(result, response)
    }
  }
}

我需要测试一下

result.then(res => {
        console.log('hey I m in !')
        callbackRender(res, response)
      })

名副其实。

我使用 mocha 和 chai 编写了这个测试,我总是有 0 次间谍调用:

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(callbackRender)
      callback(injector, routes[3])(request, response)
      setTimeout(() => {
        expect(spy).to.have.been.called.once
        mock.verify()
        mock.restore()
        done()
      }, 0)
    })

注意:如果调用得当,promise resolve 部分中的日志消息,我可以将其显示在屏幕上。

有什么想法吗?

【问题讨论】:

  • 异步代码需要异步测试。
  • 正是我对 setTimeout 所做的:o
  • 不完全...setTimeout 不会在这里帮助您(至少,不可预测)。在检查 expect 语句之前,您的测试需要 wait for the resolved promise
  • 我不知道如何让它工作。在我的情况下,我无法访问返回的承诺

标签: javascript node.js unit-testing mocha.js chai


【解决方案1】:

返回您的回复,然后您可以在测试中致电then

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 {
      return Promise.resolve(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(callbackRender)
      callback(injector, routes[3])(request, response).then(() => {
          expect(spy).to.have.been.called.once
          mock.verify()
          mock.restore()
          done()
      });
  });

虽然,你似乎没有注入 callbackRender,所以你的间谍可能仍然没有被调用。

【讨论】:

  • 我的上下文有点宽,我不能返回一个承诺,因为你看到的带有请求的回调,响应参数(第 2 行)实际上是一个快速的 Web 服务器回调。它根本不管理承诺。不过谢谢你的回复:)
  • 我不明白为什么你不能返回承诺,我经常在快递处理程序中返回承诺。没有它,您唯一的选择是设置更长的超时时间,但这很容易出错。
猜你喜欢
  • 1970-01-01
  • 2019-08-18
  • 2016-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
  • 2014-10-06
相关资源
最近更新 更多