gpt4 book ai didi

javascript - 在 promise 解析时调用私有(private)函数的单元测试模块

转载 作者:太空宇宙 更新时间:2023-11-04 00:26:27 24 4
gpt4 key购买 nike

我是 Node 单元测试的新手,在 promise 方面遇到了障碍。我的模块通过 ApiController 执行搜索,然后返回一个 promise 。根据其解析状态,它调用模块内的两个私有(private)函数之一。

模块:

module.exports.process = function(req, res) {
let searchTerm = req.query.searchValue;

ApiController.fetchResults(searchTerm)
.then((results) => onReturnedResults(results), (err) => onNoResults());

function onReturnedResults(results) {
req.app.set('searchResults', results);
res.redirect('/results');
}

function onNoResults() {
res.render('search/search', { noResultsFound: true });
}
};

测试:

var res = {
viewName: '', data : {},
render: function(view, viewData) {
this.view = view;
this.viewData = viewData;
}
};

var req = { query: { searchValue: 'doesnotexist' } }

describe('When searching for results that do not exist', function() {
it('should display a no results found message', function(done) {
let expectedResult = {
noResultsFound: true;
}

SearchController.process(req, res);

// Assert...
expect(res.viewData).to.be.equal(expectedResult);
done();
});
})

围绕此问题的最佳实践是什么以及如何“模拟” fetchResults 返回的 promise ,以便它实际上不会从 API 获取结果(同时仍然调用私有(private)函数)?

最佳答案

如果方法的作用域为闭包或为模块私有(private),则无法访问它们,只能间接验证。要提供 fetchResults 的测试实现,必须以某种方式公开它。

一种方法是 require ApiController (这可能已经发生),然后使用 proxyquiremockery覆盖依赖关系。我使用过许多测试套件,它们交互和提供测试依赖项的唯一方法是通过修补 require。使用这种方法测试套件变成了一场噩梦。清理、取消补丁、级联补丁,所有这些都会耗费大量时间,如果有其他选择,我们建议不要这样做。

另一种方法是将 fetchResults 实现更改为对象的能力。除了测试之外,使 fetchResults 可配置将有助于使您的代码免受 future 更改的影响,因为当/如果您需要获取结果的方式发生变化时,可以最大限度地减少对 process 的影响:

var Results = (function() {
return {
process: function(req, res) {
let searchTerm = req.query.searchValue;

this.fetchResults(searchTerm)
.then((results) => this.onReturnedResults(req, res, results), (err) => this.onNoResults(res)),

fetchResults: ApiController.fetchResults,

onReturnedResults: function(req, res, results) {
req.app.set('searchResults', results);
res.redirect('/results');
},

onNoResults: function(res) {
res.render('search/search', { noResultsFound: true });
}
};

})()

(我已经有一段时间没有使用 javascript 了,所以我不确定对上述对象建模的最佳方法,但重要的是,如果您的测试想要重写实现,那么实现必须是暴露,上面的代码应该这样做)

现在有一个 Results 对象,其中的 fetchResults 方法以易于重写的方式公开

var fakeFetchResults = sinon.stub();
fakeFetchResults.return(aFakePromiseWithResultsToTriggerResultsCodePath);
Results.fetchResult = fakeFetchResults;

上面公开了返回函数和错误函数,这也允许对该功能进行隔离的单元测试。

使用过程是通过结果对象完成的,您的 Controller 可以注册

结果.process

关于javascript - 在 promise 解析时调用私有(private)函数的单元测试模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42595505/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com