【问题标题】:Mocking Axios calls using Moxios in order to test API calls使用 Moxios 模拟 Axios 调用以测试 API 调用
【发布时间】:2018-02-21 02:07:03
【问题描述】:

我有以下自定义 Axios 实例:

import axios from 'axios'

export const BASE_URL = 'http://jsonplaceholder.typicode.com'

export default axios.create({
  baseURL: BASE_URL
})

对应的服务:

import http from './http'

export async function fetchUserPosts(id) {
  const reponse = await http.get(`/users/${id}/posts`)
  return reponse.data
}

这是对上述服务的测试:

import moxios from 'moxios'
import sinon from 'sinon'
import http from '@/api/http'
import { fetchUserPosts } from '@/api/usersService'

describe('users service', () => {
  beforeEach(() => {
    moxios.install(http)
  })

  afterEach(() => {
    moxios.uninstall(http)
  })

  it('fetches the posts of a given user', (done) => {
    const id = 1
    const expectedPosts = ['Post1', 'Post2']

    moxios.stubRequest(`/users/${id}/posts`, {
      status: 200,
      response: expectedPosts
    })

    const onFulfilled = sinon.spy()
    fetchUserPosts(1).then(onFulfilled)

    moxios.wait(() => {
      expect(onFulfilled.getCall(0).args[0].data).toBe(expectedPosts)
      done()
    })
  })
})

使用 Karma + Jasmine 执行时会引发以下错误:

Uncaught TypeError: Cannot read property 'args' of null thrown

我想测试的是,当端点/users/{id}/posts 被击中时,会发回一个模拟响应。所有这一切都是在使用我的自定义 axios 实例http

我已经尝试将存根作为 moxios shows 文档的第一个示例。但是我认为这不适合我的用例,因为我想检查请求在我的服务中是否正确形成。

我也尝试使用以下代码,它按预期工作,但是我想测试我的服务(以下代码不这样做):

import axios from 'axios'
import moxios from 'moxios'
import sinon from 'sinon'

describe('users service', () => {
  beforeEach(() => {
    moxios.install()
  })

  afterEach(() => {
    moxios.uninstall()
  })

  it('fetches the posts of a given user', (done) => {
    const id = 1
    const expectedPosts = ['Post1', 'Post2']

    moxios.stubRequest(`/users/${id}/posts`, {
      status: 200,
      response: expectedPosts
    })

    const onFulfilled = sinon.spy()
    axios.get(`/users/${id}/posts`).then(onFulfilled)

    moxios.wait(() => {
      expect(onFulfilled.getCall(0).args[0].data).toBe(expectedPosts)
      done()
    })
  })
})

关于如何修复错误的任何想法?

【问题讨论】:

    标签: javascript unit-testing axios moxios


    【解决方案1】:

    我知道这是一个老问题,但是当我遇到同样的问题时,我会发布我的方法:

    在这种情况下你不需要使用sinon,因为你有一个axios的实例,用它来配置moxios(就像你已经做过的那样)

    beforeEach(() => {
        moxios.install(http)
      })
      afterEach(() => {
        moxios.uninstall(http)
    })
    

    然后你像这样测试你的方法:

    it('test get', async () => {
         const expectedPosts = ['Post1', 'Post2']
    
         moxios.wait(() => {
              const request = moxios.requests.mostRecent()
              request.respondWith({ status: 200, response: expectedPosts }) //mocked response
         })
    
         const result = await fetchUserPosts(1)
         console.log(result) // ['Post1','Post2'] 
         expect(result).toEqual(expectedPosts)
    })
    

    就是这样。

    问候

    【讨论】:

    • 嘿,我收到了超时 - 在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时内未调用异步回调。
    • 如果没有看到您正在使用的代码,我就忍不住了,但我认为您的问题是 async 测试...检查您的 it 签名。查看此链接stackoverflow.com/questions/22604644/… 了解更多信息
    • @ElmerDantas:我很想知道什么时候将 moxios.stubRequest 放在 moxios.wait() 之外,什么时候将它放在 moxios.wait() 中?我仍在试图弄清楚网络调用的整个模拟是如何工作的。 stubRequestrespondWith 一样吗?如果您将 request.respondWith 放在 moxios.wait() 之外,您的解决方案会起作用吗? moxios.wait() 中的代码何时真正被调用?谢谢
    • @YeasirArafatMajumder respondWith 是来自request 的函数(来自moxios.requeststubRequest 是来自moxios 的函数,您可以将其与sinon...一起使用稍后您可以指定要测试的确切 URL,但您需要 sinon 来帮助您。据我所知,您必须在 wait 中执行代码,因为您必须等到异步操作完成才能使用结果。你可以随时阅读docs
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-15
    • 2021-04-18
    • 2020-11-06
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    相关资源
    最近更新 更多