unit-testing - Vue with jest - 使用异步调用进行测试

标签 unit-testing vue.js vuejs2 jestjs

如何让我的测试等待我的 api 的结果? 我正在使用 vue 和 jest 来测试我的组件。

我想测试将客户端写入我的数据库的方法。在我的组件中,我有以下方法:

methods: {

  onSubmitClient(){

   axios.post(`urlApi`, this.dados).then(res => {

      return res;
   })

  }
}

在我的测试中

describe('login.vue', () => {

  let wrapper

  beforeAll(()=>{

    wrapper = mount(client, {
      stubs: ['router-link'],
      store,
      data() {
          return {
              dados: {
                  name: 'tes name',
                  city: 'test city'
              },
          };
      }
    })
  })

  it('store client', () => {

    res = wrapper.vm.onSubmitLogin()
    console.log(res);

  })

})

我的测试不会等待 API 调用完成。我需要等待 API 调用才能知道测试是否有效。如何让我的测试等待 API 返回?

最佳答案

您的代码中存在多个问题。

首先,您不能返回 from an async call .相反,您可能应该在 onSubmitClient 中设置一些数据,并返回整个 axios 调用,这是一个 Promise。例如:

onSubmitClient(){
  return axios.post(`urlApi`, this.dados).then(res => {
      this.result = res;
      return res;
  })
}

我假设这里的方法是从服务器存储一个结果。也许你不想要那个;这只是一个例子。我稍后会回来讨论它。

好的,现在,您可以在包装器中调用 onSubmitClient 并查看是否已设置 this.result。如您所知,这并不简单。

为了让一个 Jest 测试等待异步代码,you need either to provide a done callback function or return a promise .我将展示一个前者的例子:

it('store client', (done) => {
  wrapper.vm.onSubmitLogin().then((res) => {
    expect(wrapper.vm.dados).toEqual(res);
    done();
  })
});

现在这段代码应该可以正常工作了,但它仍然存在问题,正如@jonsharpe 在评论中所说。

您通常不想在单元测试中执行真实网络请求,因为它们速度慢且不可靠。此外,单一测试旨在隔离测试组件,在这里我们不仅测试我们的组件在发出请求时正确设置this.result。我们还在测试是否有一个正在运行的网络服务器正在运行。

因此,在这种情况下,为了测试单个功能,我会做的是将请求提取到另一个方法,使用 vue-test-utils 对其进行模拟> 和 jest.fn,然后断言 onSubmitClient 完成了它的工作:

组件:

export default {
  data() {
    return {
      http: axios,
      ...
    },
    methods: {

      onSubmitClient(){
        this.http.post(`urlApi`, this.dados).then(res => {
            this.result = res;
        })
      }
    }
  }
}

测试:

it('store client', (done) => {
  const fakeResponse = {foo: 'bar'};
  var post = jest.fn();
  var http : {
    post,
  };
  var wrapper = mount(client, {
    stubs: ['router-link'],
    store,
    data() {
      return {
        dados: {
            name: 'tes name',
            city: 'test city'
        },
        http, //now, the component under test will user a mock to perform the http post request.
      }
      }
  });
  wrapper.vm.onSubmitLogin().then( () => {
    expect(post).toHaveBeenCalled();
    expect(wrapper.vm.result).toEqual(fakeResponse);
    done();
  })

});

现在,您的测试断言了两件事:

  1. post 被调用。
  2. this.result 已按应有的方式设置。

如果您不想在组件中存储来自服务器的任何内容,只需删除第二个断言和方法中的 this.result = res 行即可。

所以基本上这涵盖了为什么您的测试不等待异步请求以及代码中的一些问题。还有一些事情需要考虑(例如,我认为全局 wrapper 是个坏主意,在测试组件时我总是更喜欢 shallowMount 而不是 mount行为),但这个答案应该对你有很大帮助。

PS:没有测试代码,所以可能我搞砸了。如果它不起作用,请查找语法错误或类似问题。

关于unit-testing - Vue with jest - 使用异步调用进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51812626/

相关文章:

unit-testing - 相当于 FakeItEasy 中 JustMock 的 ReturnsCollection() 吗?

javascript - Vue - 导航到下一个子路线

javascript - Vue.js - 更新路由器 View

javascript - Vue.js - 如何按特定属性对数组内的对象进行排序并使用 "v-for"渲染它

android - 如何在 android 中使用 Dagger 对 kotlin 文件进行 UI 测试?

javascript - ReactJS 的首选测试方法?

ios - XCTestCase 中的 WKInterfaceController 子类上的 "alloc init"崩溃

javascript - 无法将第二个参数发送到 Vue 商店中的突变

javascript - 可折叠 Accordion 组件中的 Vue 加载组件

node.js - Vue 组件文件仅在 Windows 上构建时存在语法错误