unit testing使用服务方法的节点js控制器的最佳方法是什么?

我的控制器=>下面的控制器是使用reqpoertService.getFiles方法,该方法本身使用外部的API来调用数据。

function getFiles(req, res) { reportService.getFiles({ fromDate: req.query.fromdate, endDate: req.query.enddate, fileTypes: req.query.filetypes || [], fileStatus: req.query.filestatus || [] }) .then(data => { logger.info('-> reportService.getFiles :: Successfully fetched data', resolveLogger({ statusCode: res.statusCode }) ); res.send(data); }) .catch(err => { logger.error('<- OOPS :: reportService.getFiles fail to fetch data'); res.status(statusCodes.INTERNAL_SERVER_ERROR).send({}); logger.error('<- ERROR', resolveLogger({ statusCode: res.statusCode, errMessage: err.message, errorStack: err })); }); } 

记者服务

 function getFiles() { return new Promise((resolve, reject) => { requestPromise(options) .then(data => { var duration = new Date - start; logger.info(resolveLogger({ duration: duration + 'ms', reqUrl: options.url, bodyLengh: data && data.length })); logger.info('<= Request complete successfully.'); var resData = JSON.parse(data); resolve(resData); }) .catch(error => { logger.error('=> Request failed for URL:', options.url); reject(error); }); }); } 

我的unit testing方法来testing上面的控制器

 it('METHOD: getFiles -> should response 500 without data', done => { nock('http://localhost:1708/fakeapi') .get('/files') .reply(statusCodes.INTERNAL_SERVER_ERROR); const res = buildResponse(); const req = httpMocks.createRequest({ method: 'GET', url: '/api/submitted-data/1/files' }); res.on('end', function () { var data = res._getData(); expect(data).toEqual({}); expect(statusCodes.INTERNAL_SERVER_ERROR).toBe(res.statusCode); done(); nock.cleanAll(); }); reporterController.getFiles(req, res); }); 

有人可以build议我遵循的方法是可以接受的,还是有更好的方法来做unit testing。 因为我是初学者做unit testing。

我认为你的方法是正确的。 你的testing应尽可能多地从实现中分离出来。 所以你的testing代码不应该知道你是如何实现你的代码的。 它只是关心,当你达到你的终点,结果如预期。 您想要模拟代码的外部部分,即运行testing(如外部API)时不会执行的代码。 您可以嘲笑外部API的某些响应,以便您可以编写testing来覆盖这些types的场景,然后按需要处理它们。

ThoughtWorks的这篇文章对解释这种testing方法非常有帮助: https : //www.thoughtworks.com/insights/blog/mockists-are-dead-long-live-classicists

我还build议观看这个video标题Ian Cooper:TDD哪里出了问题: https : //vimeo.com/68375232

我很欣赏我的build议是一个很高的水平,所以总之我认为你的testing应该是这样的:

  1. build立你的testing环境,设置数据等。所以在你的情况下,确保存在一个文件(如果来自外部API,这可能是模拟的响应)
  2. 设置嘲笑你的外部apis(如果外部api超时,down,401,500等)。
  3. 打电话给你的API
  4. 断言你的API端点返回的结果

然后,您可以进行不同的testing,检查外部API返回的不同响应。

我有一个unit testing的批评,那就是你没有使用beforeAll / each来真正设置你的testing。

我的意思是:

  • 您可以使用“it”嵌套的describe块来声明在testing设置期间将被设置的variables(beforeEach / All),并且应该是在“it”期间实际“期望”的variables。
  • “它本身应该更干净,更小,几乎只是由期望组成。

公寓从它看起来不错。