如何测试调用多个其他函数的函数?

时间:2019-06-27 13:22:43

标签: javascript unit-testing express mocha

我正在编写一个ExpressJS中间件,该中间件可以稍微修改请求对象并检查用户是否有权访问该特定页面。我对它进行单元测试有问题。我为除handler之外的所有方法编写了单独的测试。如何测试handler功能?我应该测试吗?还是因为涵盖了所有其他功能,我应该只用istanbul ignore next忽略它吗?还是我应该以某种方式重写我的handler函数以使其可测试?

class Example {

constructor(request, response, next, userAccountService) {
    this.req = request;
    this.res = response;
    this.next = next;
    this.userAccountService = userAccountService;
}

removeTokenFromQuery() {
    delete this.req.query.token;
}

isValidRequest() {
    if (!this.req.secure) {
        return false;
    }

    if (typeof this.req.query.token !== 'undefined') {
        return false;
    }

    if (typeof this.req.query.unsupportedQueryParam !== 'undefined') {
        return false;
    }

    return true;
}

isPageAccessibleForUser() {
    return this.userAccountService.hasAccess('example');
}

async handler() {
    this.removeTokenFromQuery();

    if (!this.isValidRequest()) {
        throw new Error('Invalid request');
    }

    if (!this.isPageAccessibleForUser()) {
        this.res.statusCode(500);
        this.res.end();
        return;
    }

    this.next();
}

}

然后称为Express中间件:

this.app.use((res, req, next) => {
    const exampleObj = new Example(res, req, next, userAccServ);
    exampleObj.handler();
});

1 个答案:

答案 0 :(得分:1)

我应该测试它吗?

是的,根据您的示例处理程序,它包含(看起来应该是)一些关键业务逻辑。它负责编排

  • 从请求中删除令牌(安全性)
  • 确定请求是否有效(安全性/身份验证)
  • 确定用户是否可以访问页面(安全性/身份验证)

如果未测试此功能,将来的工程师可能会对此重要功能进行修改,并且他们将不会收到有关更改的任何反馈。假设他们从人为错误中意外删除了isValidRequest检查?或删除了!。但是,与进行测试所需的相对较少的工作量相比,与这种情况相关的风险不太可能是灾难性的。

如何测试处理程序功能?

接下来的问题是您如何实际测试此方法:)我将选择在可能的最低“级别”下进行测试较低(通过直接调用此方法与较高< / strong>(通过快速框架)。

您已经提到,handler委托给每个功能的实现都有测试,IMO在handler中测试的重要内容是流程而不是实现(因为那些实现已经过测试)。

describe('handler()', () => {
  it('removes token from query');
  it('errors on invalid request');
  it('returns 500 status code when page is inaccessible');
  it('continues with .next() when request is valid and page is accessible');
})

为此,我将实例化Example,然后修补必要的方法,以便为您的handler()测试创建正确的流程。因此对于无效的请求测试,它可能类似于:

const example = new Example();
sinon.stub(example, "isValidRequest").returns(false);

如果未进行存根比这些测试实质上重复了其他测试(通过测试实际实现)。使用存根可以更改isValidRequest的实现,同时在handler中保持单元测试保护