Vue开玩笑-使用异步调用进行测试

时间:2018-08-12 20:33:40

标签: 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返回?

1 个答案:

答案 0 :(得分:6)

您的代码中有几个问题。

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

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

我认为这里的方法是从服务器存储result。也许你不想要那个。这只是一个例子。我待会儿再讲。

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

为了使测试能够等待异步代码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);
  })
});

现在,此代码应该可以使用,但是仍然存在问题,如@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;
        })
      }
    }
  }
}

测试:

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:没有测试代码,所以也许我搞砸了。如果事情不起作用,请查找语法错误或类似问题。