简体   繁体   English

这些 Jest 测试的顺序如何影响测试结果?

[英]How come the order of these Jest tests affect the test outcome?

I cannot figure out why the order of these jest tests affects the test outcome.我不明白为什么这些笑话测试的顺序会影响测试结果。

This order allows all of the tests to pass:此顺序允许所有测试通过:

import $axios from "@/services/backend-service";
import actions from "@/store/modules/transactions/actions";

describe("store/modules/transactions/actions", () => {
  let state;
  let postSpy;
  beforeEach(() => {
    state = {
      commit: jest.fn(),
    };
    postSpy = jest.spyOn($axios, "post");
  });

  it("starts uploading transactions", async () => {
    postSpy.mockImplementationOnce(() => {
      return Promise.resolve();
    });

    await actions.uploadTransactions(state, { file: "arbitrary filename" });
    $axios.interceptors.request.handlers[0].fulfilled();

    expect(state.commit).toHaveBeenCalledWith("changeUploadStatusToUploading");
  });

  it("succeeds uploading transactions", async () => {
    postSpy.mockImplementationOnce(() => {
      return Promise.resolve();
    });

    await actions.uploadTransactions(state, { file: "arbitrary filename" });

    expect(state.commit).toHaveBeenCalledWith("changeUploadStatusToSucceeded");
  });
});

This order:这个命令:

import $axios from "@/services/backend-service";
import actions from "@/store/modules/transactions/actions";

describe("store/modules/transactions/actions", () => {
  let state;
  let postSpy;
  beforeEach(() => {
    state = {
      commit: jest.fn(),
    };
    postSpy = jest.spyOn($axios, "post");
  });

  it("succeeds uploading transactions", async () => {
    postSpy.mockImplementationOnce(() => {
      return Promise.resolve();
    });

    await actions.uploadTransactions(state, { file: "arbitrary filename" });

    expect(state.commit).toHaveBeenCalledWith("changeUploadStatusToSucceeded");
  });

  it("starts uploading transactions", async () => {
    postSpy.mockImplementationOnce(() => {
      return Promise.resolve();
    });

    await actions.uploadTransactions(state, { file: "arbitrary filename" });
    $axios.interceptors.request.handlers[0].fulfilled();

    expect(state.commit).toHaveBeenCalledWith("changeUploadStatusToUploading");
  });
});

causes this error:导致此错误:

  ● store/modules/transactions/actions › starts uploading transactions

    expect(jest.fn()).toHaveBeenCalledWith(...expected)

    Expected: "changeUploadStatusToUploading"
    Received: "changeUploadStatusToSucceeded"

    Number of calls: 1

      29 |     $axios.interceptors.request.handlers[0].fulfilled();
      30 |
    > 31 |     expect(state.commit).toHaveBeenCalledWith("changeUploadStatusToUploading");
         |                          ^
      32 |   });
      33 |
      34 |

      at Object.<anonymous> (tests/unit/store/modules/transactions/actions.spec.js:31:26)

I suspect it has to do with hoisting and this thread: https://github.com/facebook/jest/issues/2582我怀疑它与提升和这个线程有关: https://github.com/facebook/jest/issues/2582

But have not been able to wrap my head around it.但是一直无法绕过它。

Thank you for your time and help谢谢你的时间和帮助

Below are the other bit of code that might be relevant:以下是可能相关的其他代码:
actions.js : actions.js

import $axios from "@/services/backend-service";

const RESOURCE_NAME = "transaction";
const RESOURCE_PATH = `${RESOURCE_NAME}s`;

export const actions = {
  uploadTransactions(state, payload) {
    let formData = new FormData();
    formData.append("account_id", 1); // change to get dynamically when ready
    formData.append("file", payload["file"]);

    $axios.interceptors.request.use(function (config) {
      state.commit("changeUploadStatusToUploading");
      return config;
    });

    return $axios
      .post(`${RESOURCE_PATH}/batch_upload/`, formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
      })
      .then(() => {
        state.commit("changeUploadStatusToSucceeded");
      })
      .catch(function (error) {
        state.commit("changeUploadStatusToFailed");
      });
  },
};

export default actions;

backend-service.js : backend-service.js

import axios from "axios";

const API_BASE_URL =
  `${process.env["VUE_APP_BACKEND_SCHEME"]}` +
  `://` +
  `${process.env["VUE_APP_BACKEND_HOST"]}` +
  `:` +
  `${process.env["VUE_APP_BACKEND_PORT"]}` +
  `/` +
  `${process.env["VUE_APP_BACKEND_PATH_PREFIX"]}`;

const $axios = axios.create({
  baseURL: API_BASE_URL,
  headers: {
    "Content-Type": "application/vnd.api+json",
  },
});

export default $axios;

In the case where all tests pass, you have invoked the interceptors yourself in the very first test, so following things happened in the given order:在所有测试都通过的情况下,您在第一个测试中自己调用了拦截器,因此以下事情按给定顺序发生:

(1) state.commit --> calledWith --> changeUploadStatusToUploading

(2) Manually invoked interceptor

(3) Interceptor execution finished successfully

(3) Response finished successfully

(4) state.commit --> calledWith --> changeUploadStatusToSucceeded

In the case where tests fail, the first test didn't invoke interceptors, so following things happened:在测试失败的情况下,第一个测试没有调用拦截器,所以发生了以下事情:

(1) state.commit --> calledWith --> changeUploadStatusToUploading

(2) interceptor not invoked

(3) response hasn't ended yet

(4) State.commit wasn't called anymore since interceptor needs to be resolved first

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM