我有使用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
,但我似乎无法通过测试获取它,这意味着我的测试实际上是在进行电话号码验证服务。
我有什么方法可以绕过该验证服务吗?
答案 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
的原型。你可以 通过编辑ctx
向app.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
方法后,将会有效,而不是原始方法。