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

Ren*_*ira 1 unit-testing vue.js jestjs vuejs2

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

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

methods: {

  onSubmitClient(){

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

      return res;
   })

  }
}
Run Code Online (Sandbox Code Playgroud)

在我的测试中

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);

  })

})
Run Code Online (Sandbox Code Playgroud)

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

Ser*_*eon 6

您的代码中存在几个问题.

首先,你不能return 从异步调用.相反,你可能应该在你的设置中设置一些数据onSubmitClient,并返回整个axios调用,这是一个Promise.例如:

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

我假设这里的方法是result从服务器存储a .也许你不想那样; 这只是一个例子.我稍后会回来.

好的,现在,你可以调用onSubmitClient你的包装器,看看是否this.result已经设置好了.如您所知,这不是直截了当的.

为了使jest测试等待异步代码,您需要提供done回调函数或返回promise.我将展示前者的一个例子:

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

现在这个代码应该可行,但仍然存在问题,正如@jonsharpe在评论中所说的那样.

您通常不希望在单一测试中执行真实的网络请求,因为它们很慢且不可实现.此外,单一测试旨在单独测试组件,在这里我们不仅测试我们的组件在请求时正确设置this.result.我们还在测试是否有正在运行的Web服务器正在运行.

所以,我会在这种情况下,测试做的是单件的功能,是提取要求的另一种方法,用嘲笑它vue-test-utilsjest.fn,然后断言onSubmitClient做的工作:

组件:

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

      onSubmitClient(){
        this.http.post(`urlApi`, this.dados).then(res => {
            this.result = res;
        })
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

考试:

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();
  })

});
Run Code Online (Sandbox Code Playgroud)

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

  1. post 被叫.
  2. this.result 设置应该是.

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

所以基本上这涵盖了为什么您的测试不等待异步请求和代码中的一些问题.还有一些事情要考虑(FI我认为一个全球性的wrapper坏主意,我总是喜欢shallowMountmount测试组件的行为时),但这个答案应该帮助你很多.

PS:没有测试代码,所以也许我搞砸了什么.如果事情不起作用,请查找语法错误或类似问题.