eggmock单元测试service时,有提供方法mock出ctx.request.body吗?
发布于 4 年前 作者 yao17 4701 次浏览 来自 问答

背景:

  • 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层?
初次提问,不知道有没有描述清楚我的问题?另外如果有不妥的地方可以直接跟我说。提前感谢各位的回答~

7 回复

service 层是业务逻辑了,在这一层你不应该去处理 ctx.request.body 等跟协议层有关的事,应该在 Controller 提取后作为参数调进来

请求 响应 放在控制器里面 , 业务逻辑放在service里面

@atian25 好的吧 似乎只能这样了。那我只能直接测试Controller了。不过谢谢您鸭~

@youmenglinzi 嗯嗯,理论上是这样,不过当初写的时候就可能贪方便可以写少一些传递的参数导致这样,才想着有没有办法可以在service模拟出request的。既然egg-mock没有这样的函数那我就另外找办法啦。谢谢您~

@yao17 如果这样的话你都没必要写 Service 了,因为你都不分层了。

@yao17 请求入参都需要在 controller 处理掉,包括校验、安全什么的。

嗯嗯,把入参放到service是不符合controller\service\model这样的设计啦,也谢谢各位的解答~

回到顶部