【问题标题】:Unit test handler that contains promise包含承诺的单元测试处理程序
【发布时间】:2019-10-21 21:18:17
【问题描述】:

我有 TDD 知识,并且我一直在尝试使用相同的原理在 javascript 中启动一个项目。

我正在构建一个 API,一旦命中,就会向外部服务发出请求以收集一些数据,一旦检索到,就会对其进行解析并返回响应。

到目前为止,我的传奇一直很不幸,我搜索了很多,我发现的最相似的问题是这个one。但是我没有成功应用相同的解决方案。

我在实现端的实现如下:

//... other handlers
weather(request, response) {
    //... some setup and other calls
    this.externalService.get(externalURL)
        .then(serviceResponse => {
            this.externalResponseParser.parse(serviceResponse)
        });
    //... some more code
}

在测试方面:

let requester;
let mockParser;
let handler;
let promiseResolve;
let promiseReject;

beforeEach(function () {
    requester = new externalRequesterService();
    mockParser = sinon.createStubInstance(...);

    handler = new someHandler({
        externalService: requester,
        externalResponseParser: mockParser
    });
});

it('returns data', function () {
    sinon.stub(requester, 'get').callsFake((url) => {
        return new Promise((resolve, reject) => {
            // so I can be able to handle when the promise gets resolved
            promiseResolve = resolve;
            promiseReject = reject;
        });
    });

    handler.weather(request, response);

    // assertions of what happens before externalService.get gets called - all green

    promiseResolve(expectedServiceResponse);

    assert.ok(mockExternalResponseParser.parse.calledOnce, 'Expected externalResponseParser.parse to have been called once');
});

在测试的最后一行,它失败了,即使我正在调用我应该调用的。 在某些时候,我添加了一些日志记录,并且我能够看到 then 块的代码似乎在测试中的断言之后被执行,这可能是问题的根源。

我试图找出是否有某种eventually 可以使用,所以我在解决承诺后的断言会是这样的:

assert.eventually(mockExternalResponseParser.parse.calledOnce, 'Expected externalResponseParser.parse to eventually be called once');

但没有运气。

有人对缺少的内容有明确的解释吗?非常感谢提前

P.S.- 根据要求,请找到我的代码 here 的精简版。只需运行 npm install,然后运行 ​​npm test 即可获得相同的输出。

【问题讨论】:

  • 如何在handler.weather(request, response); 中获取responserequest?另外,如果您可以提供代码沙箱,我可以提供帮助
  • 嗨@SakhiMansoor,我已经更新了我的问题,并提供了指向github存储库的链接,在那里我得到了同样的错误。我已经把它剥离了,但我认为所有关键元素都在那里,因为我仍然得到相同的输出。希望能帮助到你。非常感谢。

标签: javascript unit-testing promise mocha.js sinon


【解决方案1】:

感谢大家花费的时间。

我最终在Medium 上找到了这篇非常好的文章,它让我能够解决我的问题。它有一个很好的解释,从回调到承诺,这正是我手头的场景。

我已经更新了我创建的 github 存储库以了解如何修复它。

如果您想TL;DR,这里只是更改的亮点。实施方面:

async weather(request, response) {
    //...

    let serviceResponse = await this.requesterService.get(weatherURL);

    //...
};

在测试方面:

it('returns weather on success', async function () {
    sinon.stub(requester, 'get').callsFake((_) => {
        return new Promise((resolve, _) => {
            resolve(expectedServiceResponse);
        });
    });

    await handler.weather(request, response);

    //...
    assert.ok(mockWeatherParser.parseWeather.calledOnce, 'Expected WeatherParser.parseWeather to have been called once'); // no longer fails here
    //...
});

现在请记住,在此示例中,它仍然是同步的。但是,我已经逐步改进了我的 API,在使用 Promises 迁移到这个同步版本之后,迁移到异步版本要容易得多。在测试和实施方面。

如果您有同样的问题并需要帮助或有疑问,请告诉我。我很乐意提供帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-01
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多