如何在测试NodeJS API时模拟外部服务

时间:2015-12-02 06:32:22

标签: node.js integration-testing koa superagent koa2

我有使用koa构建的JSON API,我试图用集成测试来覆盖它。

一个简单的测试看起来像这样:

      describe("GET: /users", function() {
        it ("should respond", function (done) {
          request(server)
          .get('/api/users')
          .expect(200, done);
        });
      });

现在问题出现在控制器背后的操作 - 让我们在POST / users说saveUser - 使用外部资源。例如,我需要验证用户的电话号码。

我的控制器如下所示:

  save: async function(ctx, next) {
    const userFromRequest = await parse(ctx);
    try {
      // validate data
      await ctx.repo.validate(userFromRequest);

      // validate mobile code
      await ctx.repo.validateSMSCode(
        userFromRequest.mobile_number_verification_token,
        userFromRequest.mobile_number.prefix +  userFromRequest.mobile_number.number
      );

      const user = await ctx.repo.create(userFromRequest);

      return ctx.data(201, { user });
    } catch (e) {
      return ctx.error(422, e.message, e.meta);
    }
  }

我希望能够在请求对象上模拟ctx.repo,但我似乎无法通过测试获取它,这意味着我的测试实际上是在进行电话号码验证服务。

我有什么方法可以绕过该验证服务吗?

2 个答案:

答案 0 :(得分:0)

您是否考虑过使用像https://github.com/mfncooper/mockery这样的模型库?

通常,在编写需要外部服务的测试时,我会模拟服务客户端库模块。例如,使用mocha:

mockery = require('mockery');
repo = require('your-repo-module');

before(function() {
  mockery.enable();

  repo.validateSMSCode = function() {...};

  mockery.registerMock('your-repo-module', repo);
}

这样,每次需要你的repo-module时,都会加载模拟模块而不是原始模块。直到你禁用模拟,显然......

答案 1 :(得分:-1)

  

app.context是创建ctx的原型。你可以   通过编辑ctxapp.context添加其他属性。这是   用于向ctx添加属性或方法以在您的网站中使用   整个app,可能更高效(无中间件)和/或更容易   (require()更少ctx ss,而更多依赖于app.context.someProp = "Some Value"; app.use(async (ctx) => { console.log(ctx.someProp); }); ,这可能   被视为反模式。

app.context.repo.validateSMSCode

对于您的示例,您可以重新定义import app from '../app' import supertest from 'supertest' app.context.repo.validateSMSCode = async function(ctx, next) { // Your logic here. }; const request = supertest.agent(app.listen()) ,假设您的测试中有以下设置行:

app.context.repo.validateSMSCode

重新定义您将在测试中定义的$scope.sameAddress = false方法后,将会有效,而不是原始方法。