背景:
- service代码是类似这样的:
async getUserInfo() {
const { ctx } = this;
const { targetUid } = ctx.request.body;
return await ctx.model.user.getUserInfo(targetUid);
}
先不考虑为什么在service层获取请求的参数,想知道
在我对这个service进行单元测试时,我能够模拟出ctx.request.body,以保证对这个service的单元测试能够进行下去吗?
我在service.test.js中,尝试这样去模拟:
it.only('should return userInfo when operating correctly', async () => {
//mock ctx与request
const ctx = app.mockContext({
request: {
body: {
targetUid: '123'
}
}
})
const result = await ctx.service.user.getUserInfo();
assert(result);
})
但是这样在service中找不到targetUid的,反而我会在ctx.req中找到我定义的request.body.targetUid。
我查了koa中的资料,好像说req是原生的请求对象,而request则是koa在req基础上封装了新的方法,但似乎并不能称作相似的对象。
我也知道似乎egg-mock可以通过app.httprequest()去测试整个controller,但有没有办法只测试service层?
初次提问,不知道有没有描述清楚我的问题?另外如果有不妥的地方可以直接跟我说。提前感谢各位的回答~
service 层是业务逻辑了,在这一层你不应该去处理 ctx.request.body
等跟协议层有关的事,应该在 Controller 提取后作为参数调进来
请求 响应 放在控制器里面 , 业务逻辑放在service里面
@atian25 好的吧 似乎只能这样了。那我只能直接测试Controller了。不过谢谢您鸭~
@youmenglinzi 嗯嗯,理论上是这样,不过当初写的时候就可能贪方便可以写少一些传递的参数导致这样,才想着有没有办法可以在service模拟出request的。既然egg-mock没有这样的函数那我就另外找办法啦。谢谢您~
@yao17 如果这样的话你都没必要写 Service 了,因为你都不分层了。
@yao17 请求入参都需要在 controller 处理掉,包括校验、安全什么的。
嗯嗯,把入参放到service是不符合controller\service\model这样的设计啦,也谢谢各位的解答~