2015-12-02 5 views
2

У меня есть JSON API, построенный с помощью koa, который я пытаюсь покрыть интеграционными тестами.Как издеваться над внешним сервисом при тестировании NodeJS API

Простой тест будет выглядеть следующим образом:

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

Теперь проблема возникает, когда действия за контроллер - позволяет говорить saveUser на POST/пользователей - использование внешних ресурсов. Например, мне нужно проверить номер телефона пользователя.

Мой контроллер выглядит следующим образом:

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 на объекте запроса, но я не могу показаться, чтобы иметь возможность ухватить на него из теста, это означает, что мои тесты фактически находят службу проверки номера телефона.

Есть ли какие-либо способы, которыми я мог бы воспользоваться удалением этой службы проверки?

+0

Попробуйте найти способ изменения 'ctx' в вашем тесте. Вы могли бы заменить 'ctx.repo' перед запуском фактического контроллера на свой собственный макет. –

ответ

0

app.context является прототипом, из которого ctx создается из. Вы можете добавить дополнительные свойства к ctx, отредактировав app.context. Это полезно для добавления свойств или методов ctx, которые будут использоваться по вашему всему app, который не может быть более производительным (без промежуточного слоя) и/или проще (меньше require() s) за счет того, чтобы полагаться больше на 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 метод, который ваш будет определять в вашем тест, будет работать, а не оригинальный метод.

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

Таким образом, каждый раз, когда потребуется ваш репо-модуль, то издевался модуль будет загружен, а не оригинал. Пока вы не отключите макет, очевидно ...

Смежные вопросы