Programing

jest.fnmus는 부르지 않았다고 주장하지만, 지금까지.

c10106 2022. 4. 12. 19:00
반응형

jest.fnmus는 부르지 않았다고 주장하지만, 지금까지.

경로에 특정 매개 변수가 있을 때 내 Vuex 저장소에서 특정 작업을 호출하는 Vue 구성 요소를 테스트하는 중.로 그 행동을 조롱하고 있다.jest.fn().

구성 요소의 관련 코드:

await this.$store.dispatch('someOtherAction');
if (this.$route.params && this.$route.params.id) {
    this.$store.dispatch('selection/selectElement', parseInt(this.$route.params.id, 10));
}

여기에 모의 기능이 있다.

someOtherAction = jest.fn();
selectElement = jest.fn(() => console.log("selectElement has been called"));

내 테스트:

it('selects element if passed in route', async () => {
  const $route = {params: {id: '256'}};
  const wrapper = shallowMount(AbcModel, {
    mocks: {$route},
    store, localVue
  });
  expect(someOtherAction).toHaveBeenCalled();
  expect(selectElement).toHaveBeenCalled();
});

출력에서 'selectionElement has calling'을 볼 수 있다.분명히 그것은 불려졌다.그럼에도 불구하고.expect(selectElement).toHaveBeenCalled()실패하다

이것이 어떻게 가능한 걸까요?내가 조롱한 또 다른 기능과 함께 그것은 잘 작동한다.내가 기능을 조롱하는 순서를 바꾸는 것은 중요하지 않다.다른 기능이 호출될 것이라는 기대를 없애는 것도 문제가 되지 않기 때문에 충돌처럼 보이지 않는다.

이것이 어떻게 가능한 걸까요?

expect앞서 달리고 실패하다selectElement도망칠 기회가 있었어


세부 사항

메시지 대기열

JavaScript는 메시지 큐를 사용한다.현재 메시지는 다음 메시지가 시작되기 전에 실행되어 완료된다.

PromiseJobs 대기열

ES6는 "약속 해결에 대한 응답"인 작업을 처리하는 PromiseJobs 대기열을 도입했다.PromiseJobs 대기열의 모든 작업은 현재 메시지가 완료된 후 다음 메시지가 시작되기 전에 실행된다.

비동기/기다리다

async그리고await약속이나 발전기보다 통사당일 뿐이야호출await에서Promise기본적으로 다음 시간에는 PromiseJobs에서 스케줄링되는 콜백으로 나머지 기능을 래핑한다.Promise결심하다

무슨 일이 일어나는가

현재 실행 중인 메시지로 테스트 실행이 시작됨.호출shallowMount다음까지 실행되는 구성 요소를 로드하십시오.await this.$store.dispatch('someOtherAction');그 전화는someOtherFunction그리고 본질적으로 나머지 함수를 대기시켜Promise콜백(callback)은 다음 경우에 PromiseJobs 대기열에서 예약됨Promise결심하다

그런 다음 실행은 두 가지를 실행하는 테스트로 되돌아간다.expect진술들그 후 첫 번째 것은 지나간다.someOtherFunction부름을 받았으나, 그 이후로 두 번째 실패는 없다.selectElement아직 달리지 않았다.

그러면 현재 실행 중인 메시지가 완료되고 PromiseJobs 대기열의 보류 중인 작업이 실행된다.호출하는 콜백selectElement대기열에 있어 실행 및 호출selectElement콘솔에 로그가 기록된다.


해결책

확실히 해라Promise콜백selectElement실행하기 전에 실행한 적이 있음expect.

가능한 경우 언제든지 를 반환하는 것이 이상적이다.Promise시험이 할 수 있도록await직접적으로

만약 그것이 가능하지 않다면, 해결책은 전화를 거는 것이다.await결의에 따라Promise기본적으로 PromiseJobs 대기열의 후면에서 테스트의 나머지 부분을 대기열에 넣고 대기 중인 모든 것을 허용하는 테스트 동안Promise먼저 실행할 콜백:

it('selects element if passed in route', async () => {
  const $route = {params: {id: '256'}};
  const wrapper = shallowMount(AbcModel, {
    mocks: {$route},
    store, localVue
  });
  expect(someOtherFunction).toHaveBeenCalled();
  // Ideally await the Promise directly...
  // but if that isn't possible then calling await Promise.resolve()
  // queues the rest of the test at the back of PromiseJobs
  // allowing any pending callbacks to run first
  await Promise.resolve();
  expect(selectElement).toHaveBeenCalled();  // SUCCESS
});

참조URL: https://stackoverflow.com/questions/54890916/jest-fn-claims-not-to-have-been-called-but-has

반응형