使用服务方法

时间:2017-08-28 14:20:07

标签: javascript node.js unit-testing jasmine

我的控制器=>下面的控制器使用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);
            });
    });
}

我的单元测试方法来测试上面的控制器

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);
});

有人可以建议我接受的方法是可以接受的,还是有更好的方法来进行单元测试。因为我是初学者进行单元测试。

2 个答案:

答案 0 :(得分:4)

我认为你的方法是正确的。您的测试应尽可能多地与实现分离。因此,您的测试代码应该不知道您是如何实现代码的。它只关心当你点击你的终点时,结果是预期的。您希望模拟代码的外部部分,即在运行测试时不会执行的代码,例如外部API。您可以模拟外部API的某些响应,以便您可以编写测试以涵盖这些类型的方案,然后根据需要处理它们。

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

我还建议观看此视频标题Ian Cooper:TDD哪里出错了:https://vimeo.com/68375232

我感谢我的建议有点高,所以总之我认为你的测试应该是这样的:

  1. 建立测试的上下文,设置数据等。因此,在您的情况下,确保存在一个文件(如果来自外部api,这可能是模拟的响应)
  2. 设置外部api的模拟(如果外部api超时,则关闭,401,500等)。
  3. 打电话给你的api
  4. 断言api端点返回的结果
  5. 然后,您可以使用不同的测试来检查外部api返回的不同响应。

答案 1 :(得分:4)

我对你的单元测试有一个批评,那就是你没有使用beforeAll / each来实际设置你的测试。

我的意思是:

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

公寓从那看起来不错。