2

我有用 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请求对象,但我似乎无法从测试中获得它,这意味着我的测试实际上是在使用电话号码验证服务。

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

4

2 回答 2

0

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

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

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

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

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

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

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

于 2016-07-08T08:50:28.907 回答
-1

app.context是从中ctx创建的原型。您可以ctx通过编辑添加其他属性app.context。这对于添加要在ctx整个.apprequire()ctx

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您将在测试中定义的方法后,它将起作用,而不是原始方法。

于 2016-06-30T11:34:13.950 回答