如何重构我的测试以使用开玩笑的手册模拟功能?

发布于 2025-01-18 09:55:11 字数 90 浏览 0 评论 0原文

我能够与Jest一起进行基本测试,但是当我尝试重构使用JEST的手动模拟功能时,该测试将不再起作用。

有什么想法,我可能做错了什么?

感谢您的时间

I am able to get a basic test working with Jest, but when I try to refactor it to use Jest's manual mocks features, the test no longer works.

Any ideas what I could be doing wrong?

Thank you for your time ????

error message:

TypeError: _backendService.default.post is not a function

      16 |
      17 |     return $axios
    > 18 |       .post(`${RESOURCE_PATH}/batch_upload/`, formData, {
         |        ^
      19 |         headers: {
      20 |           "Content-Type": "multipart/form-data",
      21 |         },

in tests/.../actions.spec.js:

//import $axios from "@/services/backend-service"; // could not get manual mock to work
import actions from "@/store/modules/transactions/actions";

//jest.mock("@/services/backend-service"); // could not get manual mock to work

// this bit of code works
jest.mock("@/services/backend-service", () => {
  return {
    post: jest.fn().mockResolvedValue(),
  };
});
// this bit of code works:end

describe("store/modules/transactions/actions", () => {
  it("uploads transactions succeeds", async() => {
    const state = {
      commit: jest.fn(),
    };

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

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

in src/.../__mocks__/backend-service.js:

const mock = jest.fn().mockImplementation(() => {
  return {
    post: jest.fn().mockResolvedValue(),
  };
});

export default mock;

in src/.../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 src/.../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("file", payload["file"]);

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

export default actions;

I've tried looking at examples from these resources, but nothing worked for me:

mocking Axios Interceptors: Mocking axios with Jest throws error “Cannot read property 'interceptors' of undefined”
overriding mock implmentations:

Jest Mock Documentation: https://jestjs.io/docs/mock-function-api#mockfnmockimplementationfn
Jest Manual Mock documentation:

using 3rd party libraries: https://vhudyma-blog.eu/3-ways-to-mock-axios-in-jest/

simple actions test example: https://lmiller1990.github.io/vue-testing-handbook/vuex-actions.html#creating-the-action

outdated actions test example:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

相守太难 2025-01-25 09:55:11

如果它帮助他人,我最终只是使用间谍,而无需使用手动模拟。

These were references that helped me figure it out:

https://silvenon.com/blog/嘲笑 - 吉斯/函数
https://silvenon.com/blog/mocking-with-with-jest-jest/modules/ < /a>
/a>

And here's the example code that ended up working for me:

in tests/.../actions.spec.js:

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("uploads transactions succeeds", async() => {
    postSpy.mockImplementation(() => {
      return Promise.resolve();
    });

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

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

  it("uploads transactions fails", async() => {
    postSpy.mockImplementation(() => {
      return Promise.reject({
        response: true,
      });
    });

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

    expect(state.commit).toHaveBeenCalledWith('changeUploadStatusToFailed');
  });
});

in src/.../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((response) => {
        console.log(response);
        state.commit("changeUploadStatusToSucceeded");
      })
      .catch(function (error) {
        if (error.response) {
          state.commit("changeUploadStatusToFailed");
        }
      });
  },
};

export default actions;

In case it helps others, I ended up just using spies and did not need to use manual mocks.

These were references that helped me figure it out:

https://silvenon.com/blog/mocking-with-jest/functions
https://silvenon.com/blog/mocking-with-jest/modules/
How to mock jest.spyOn for a specific axios call

And here's the example code that ended up working for me:

in tests/.../actions.spec.js:

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("uploads transactions succeeds", async() => {
    postSpy.mockImplementation(() => {
      return Promise.resolve();
    });

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

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

  it("uploads transactions fails", async() => {
    postSpy.mockImplementation(() => {
      return Promise.reject({
        response: true,
      });
    });

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

    expect(state.commit).toHaveBeenCalledWith('changeUploadStatusToFailed');
  });
});

in src/.../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((response) => {
        console.log(response);
        state.commit("changeUploadStatusToSucceeded");
      })
      .catch(function (error) {
        if (error.response) {
          state.commit("changeUploadStatusToFailed");
        }
      });
  },
};

export default actions;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文