使用moxios编写测试时报错:Cannot read properties of undefined (reading 'url')
moxios编写测试时报错:Cannot read properties of undefined (reading 'url')
嘿,我来帮你搞定这个moxios的报错问题!这个Cannot read properties of undefined (reading 'url')错误,大概率和你代码里axios实例的初始化方式以及测试时moxios的配置有关,咱们一步步拆解解决:
问题根源分析
- 你把
axiosInstance定义成了类的静态属性,只有当你实例化CartCreationService的时候,构造函数才会给这个静态属性赋值。如果测试代码里没先创建类的实例,这个静态实例就是undefined,moxios拦截的时候自然拿不到url属性。 - moxios默认是拦截全局的
axios实例,但你这里用的是自己创建的自定义静态实例,要是没明确告诉moxios要拦截哪一个,它就会找不到对应的请求信息,直接抛出这个错误。
具体解决步骤
1. 测试前先实例化服务并指定moxios拦截目标
在测试的钩子函数里,先实例化你的服务类,触发静态axios实例的初始化,然后让moxios明确拦截这个静态实例:
let cartService; beforeEach(() => { // 先实例化服务,触发构造函数里的axios实例初始化逻辑 cartService = new CartCreationService('test-service'); // 让moxios拦截咱们自定义的静态axios实例 moxios.install(CartCreationService.axiosInstance); }); afterEach(() => { // 测试结束后记得卸载拦截器,避免影响其他用例 moxios.uninstall(CartCreationService.axiosInstance); });
2. 优化构造函数里的静态实例初始化逻辑(可选但推荐)
你现在每次实例化CartCreationService都会重新覆盖静态的axiosInstance,这其实不太合理——静态属性是属于类的,应该只初始化一次。改成下面这样,避免重复创建实例和拦截器:
export class CartCreationService extends SuperClass { public static axiosInstance: AxiosInstance; constructor(serviceName: string) { super(serviceName); // 只有当静态实例还未初始化时才创建 if (!CartCreationService.axiosInstance) { CartCreationService.axiosInstance = axios.create({ baseURL: Configuration.NEW_CART_API, headers: { [Constants.CONTENT_TYPE]: Constants.APPLICATION_JSON, [Constants.X_API_KEY]: Configuration.CLIENT_SIDE_API_KEY, [Constants.CORRELATIONID]: Configuration.CORRELATIONID, [Constants.ADD_EFFECTIVE_PRICE]: true } }); CartCreationService.axiosInstance = Utils.setAxiosLogInterceptor(CartCreationService.axiosInstance); } } }
3. 测试用例中正确模拟请求
比如你要测试服务里的某个接口调用方法,可以这样写测试逻辑:
it('should create a cart successfully', async () => { // 模拟对应接口的响应 moxios.stubRequest('/cart', { status: 200, response: { id: 'test-cart-123' } }); // 调用服务的方法 const cartResult = await cartService.createCart(); // 断言结果符合预期 expect(cartResult.id).to.equal('test-cart-123'); });
再啰嗦下为什么之前会报错
如果测试时没先实例化CartCreationService,CartCreationService.axiosInstance就是undefined,moxios安装拦截器的时候找不到有效的axios实例,后续监听请求时自然拿不到url属性;就算实例化了,但没让moxios拦截这个自定义实例,moxios还是盯着全局的axios,抓不到你的请求,同样会抛出这个错误。
备注:内容来源于stack exchange,提问作者Sh4dy
相关产品推荐
相关产品推荐

