使用 Moxios 在 Vue 中测试 API 调用

Testing API call in Vue with Moxios

我无法弄清楚如何测试发生在 "mounted" 生命周期挂钩中的 API 调用。

我有一个文件组件负责显示有关 "Owner" 的一些信息。

这完全符合我在浏览器中的要求/期望。

<template>
  <div>
    <h3>Owner Information</h3>
    <table class="table table-striped table-condensed">
      <thead>
        <th>Name</th>
        <th>Address</th>
        <th>Social Security Number</th>
        <th>Ownership Percentage</th>
      </thead>
      <tbody>
        <tr :data-owner-id="owner.id" v-for="owner in owners">
          <td>{{ owner.name }}</td>
          <td>{{ owner.address }}</td>
          <td>{{ owner.censored_ssn }}</td>
          <td>{{ owner.ownership_percentage }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
  import axios from 'axios';

  export default {
    data() {
      return {
        principal_id: '',
        owners: []
      }
    },
    mounted() {
      const el = document.querySelector('#owner-information');
      this.principal_id = el.dataset.principal;

      var self = this;
      axios.get(`/principals/${this.principal_id}.json`).then(response => {
        response.data.owners.map((owner) => {
          owner.score = '';
          owner.link = '';
          owner.last_pull_date = '';
          self.owners.push(owner);
        });
      });
      .catch(e => {
        console.log(e);
      });
    }
  }
</script>

为了测试,我使用了 Karma、Jasmine 和 Avoriaz。

这是一个失败的测试:

import { mount } from 'avoriaz'
import OwnerInformation from '../../app/javascript/packs/OwnerInformation.vue'

describe('OwnerInformation', () => {
  let component

  beforeAll(() => {
    const element = document.createElement('div')
    element.setAttribute('id', 'owner-information')
    element.setAttribute('data-principal', '84033')
    document.body.appendChild(element)

    component = mount(OwnerInformation)
    component.vm.$mount('#owner-information')
  })

  it('retrieves owner information from the API', () => {
    expect(component.data().owners.length).toBe(1)
  })
})

以上期望为 1,但得到 0。

所以现在我认为我需要以某种方式 stub/mock 提出我的 API 请求。快速 Google 搜索使我找到了 moxios。所以我用 Yarn 安装它并最终想出了这个。我不是 100% 确定将 moxios.stubRequest 放在哪里,但尝试将它放在 beforeAll()、beforeEach() 和 "it".

```

import moxios from moxios
import { mount } from 'avoriaz'
import OwnerInformation from '../../app/javascript/packs/OwnerInformation.vue'

describe('OwnerInformation', () => {
  let component

  beforeAll(() => {
    const element = document.createElement('div')
    element.setAttribute('id', 'owner-information')
    element.setAttribute('data-principal', '12345')
    document.body.appendChild(element)

    component = mount(OwnerInformation)
    component.vm.$mount('#owner-information')
  })

  beforeEach(() => {
    moxios.install()
  })

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

  it('retrieves owner information from the API', () => {
    moxios.stubRequest('/principals/12345', {
      status: 200,
      response: {
        id: 1, owners: [
          { name: 'Test Owner', address: '123 Test St.', ssn: '123-12-1234', ownership_percentage: 100 
          }
        ]
      }
    })
    expect(component.data().owners.length).toBe(1)
  })

看起来请求实际上并没有被删除。为了排除故障,我在 axios.get() 调用(成功注销)之前放置了一个 console.log 语句,并且我还放置了一个 console.log 来注销响应,但是这个从未显示这让我觉得 axios 请求不起作用,并且没有得到 moxios 的 "intercepted"。

...
      console.log('CALLING API...')
      axios.get(`/principals/${this.principal_id}.json`).then(response => {
        console.log('***********************')
...

当我 运行 测试时,我确实看到了 404,但不确定原因:

01 08 2017 12:49:43.483:WARN [web-server]: 404: /principals/12345.json

对我来说,在 beforeAll() 顶部删除请求最有意义,但这也不起作用。

我该如何安排才能使 moxios 停止 API 请求并 returns 以便我的测试通过?

您需要使用moxios.wait()等待moxios请求完成:

/*** note the "done" argument -- you must call this method within wait()! ***/
it('retrieves owner information from the API', (done) => {
  moxios.stubRequest('/principals/12345', {
    status: 200,
    response: {
      id: 1, owners: [{ name: 'Test', address: '123 Test St.' }]
    }
  })
  moxios.wait(function() {
    expect(component.data().owners.length).toBe(1)
    done()
  })
})