首页 > 解决方案 > 使用 api 调用、提交和分派对 Vuex 操作进行单元测试

问题描述

我是使用jest的新手,想测试一个vuex 动作,它在里面做了一些事情。这是操作代码:

async [types.UPDATE_DECK_PLAN]({
  commit,
  dispatch,
  getters
}, {
  shipCode,
  deckNumber
}) {
  let deckPlan, deck;
  try {
    shipCode = shipCode !== "" ? shipCode : getters[types.SHIP_CODE];
    deckPlan = await deckPlanService.getDeckPlanByShipCode(shipCode);
    deckPlan = Helper.deckPlanTransformer(deckPlan);
    commit(types.SET_DECK_PLAN, deckPlan);
    deck = Helper.getDeckByDeckNumber(deckPlan.ships[0].decks, deckNumber);
    dispatch(types.UPDATE_SHIP, deckPlan.ships[0]);
    dispatch(types.UPDATE_DECK, deck);
    dispatch(types.UPDATE_SHIP_SVG, deckPlan.ships[0].deckPlanProfileSvg);
    dispatch(types.UPDATE_SHIP_CODE, shipCode);
    dispatch(types.UPDATE_SHIP_FEATURES, deckPlan.ships[0].shipFeatures);
  } catch (error) {
    //console.log(error);
  }
},

这是正在使用的服务:

import api from "./api";
export default {
  async getAllShips() {
    try {
      return await api.getAllShips();
    } catch (error) {
      console.log(error);
    }
  },

  async getDeckPlanByShipCode(code) {
    try {
      return await api.getDeckPlanByShipCode(code);
    } catch (error) {
      console.log(error);
    }
  }
}

这是我的测试代码:

mport actions from "../actions";
import * as types from "../../../store-types";
import deckPlanService from "@src/services/deckPlan.service";
import {deckPlan as deckPlanResponse}  from "@src/tests/mock-data/api-call-responses";
//import flushPromises from 'flush-promises';

jest.mock("@src/services/deckPlan.service", () => jest.fn());

describe("Actions", ()=>{
    describe("When Called", ()=> {
        it("Should test", async () => {
            const context = {
                commit: jest.fn(),
                dispatch: jest.fn(),
                getters: {
                    [types.SHIP_CODE]() {return "RR";}
                }
        };
            const payload = {
                shipCode: "RR",
                deckNumber: "1"
            };

            expect.assertions(1);

            deckPlanService.mockImplementation(() => ({
                getDeckPlanByShipCode: async () => Promise.resolve(deckPlanResponse)
            }));

            await actions[types.UPDATE_DECK_PLAN](context, payload);
            //await flushPromises();
            expect(context.commit).toHaveBeenCalledWith(types.SET_DECK_PLAN, deckPlanResponse);
            

        });

    });
});

但我收到此错误:

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

Expected mock function to have been called with:
  ["deckPlan/SET_DECK_PLAN", {"default": [Object], "ships": [Array], "stateroomCategories": [Array]}]
But it was not called.

    at toHaveBeenCalledWith (C:\src\static\src\scripts\vuejs\store\modules\deck-plan\__tests__\actions.spec.js:32:36)
    at tryCatch (C:\src\static\node_modules\regenerator-runtime\runtime.js:45:40)
    at Generator.invoke [as _invoke] (C:\src\static\node_modules\regenerator-runtime\runtime.js:271:22)
    at Generator.prototype.(anonymous function) [as next] (C:\src\static\node_modules\regenerator-runtime\runtime.js:97:21)
    at asyncGeneratorStep (C:\src\static\src\scripts\vuejs\store\modules\deck-plan\__tests__\actions.spec.js:27:103)
    at _next (C:\src\static\src\scripts\vuejs\store\modules\deck-plan\__tests__\actions.spec.js:29:194)
    at C:\src\static\src\scripts\vuejs\store\modules\deck-plan\__tests__\actions.spec.js:29:364
    at new Promise (<anonymous>)
    at Object.<anonymous> (C:\src\static\src\scripts\vuejs\store\modules\deck-plan\__tests__\actions.spec.js:29:97)
    at Object.asyncJestTest (C:\src\static\node_modules\jest-jasmine2\build\jasmineAsyncInstall.js:102:37)
    at resolve (C:\src\static\node_modules\jest-jasmine2\build\queueRunner.js:43:12)
    at new Promise (<anonymous>)
    at mapper (C:\src\static\node_modules\jest-jasmine2\build\queueRunner.js:26:19)
    at promise.then (C:\src\static\node_modules\jest-jasmine2\build\queueRunner.js:73:41)
    at process._tickCallback (internal/process/next_tick.js:68:7)

我究竟做错了什么?

标签: javascriptunit-testingjestjsvuex

解决方案


我对 Jest 不熟悉,但我相信您await在调用您的操作时会遗漏

const action = actions[types.UPDATE_DECK_PLAN];
await action(context, payload);

您的断言在操作完成之前运行,因此在expect执行时不会调用存根方法。


推荐阅读