Jest.js 杰斯特和莫比克斯:如何测试处理器执行?

dfuffjeb  于 2023-03-21  发布在  Jest
关注(0)|答案(1)|浏览(234)

希望有人已经克服了这个问题。codesandbox
我想检查一下,在修改appliedId之后,loadCampaign是否会被执行。正如我们在disposer中所说:
addDisposer( self, reaction(() => self.appliedIds, this.loadCampaign), );
那么我该怎么做呢?如何在jest测试中等待React执行呢?我看到here,我可以使用const reaction = jest.spyOn(mobx, 'reaction');,但我想检查disposer中执行函数的结果。
源代码/存储/筛选器/活动筛选器存储.ts

import { reaction } from 'mobx';
import { Instance, addDisposer, flow, types } from 'mobx-state-tree';

export const CampaignFull = types.model('CampaignFull', {
  id: types.identifierNumber,
  name: types.string,
  userId: types.number,
});

export type ICampaignFull = Instance<typeof CampaignFull>;

interface ICampaignData {
  id: number;
  name: string;
  userId: number;
}

export const CampaignFilterStore = types
  .model('CampaignFilterStore', {
    appliedIds: types.array(types.number),
    campaignIds: types.array(types.number),
    campaign: types.maybe(CampaignFull),
  })
  .actions((self) => ({
    afterCreate(): void {
      console.log('afterCreate');

      addDisposer(
        self,
        reaction(() => self.appliedIds, this.loadCampaign),
      );
    },
    loadCampaign: flow(function* loadCampaign(): Generator<
      Promise<ICampaignData>,
      void,
      ICampaignData
    > {
      const campaignId = self.appliedIds[0];

      console.log('loadCampaign', campaignId);

      if (!campaignId) {
        return;
      }

      try {
        const data = yield new Promise((res) => {
          setTimeout(() => {
            res({
              id: 1,
              name: 'name',
              userId: 12,
            });
          }, 500);
        });

        self.campaign = CampaignFull.create({
          id: data.id,
          name: data.name,
          userId: data.userId,
        });
      } catch (e) {
        console.error(e);
      }
    }),
    apply(): void {
      self.appliedIds.replace([...self.campaignIds]);
    },
    toggleCampaign(campaign: { id: number; name: string }): void {
      self.campaignIds.push(campaign.id);
    },
  }));

源代码/存储/筛选器/活动筛选器存储.测试.ts

import { isObservable } from 'mobx';
import { CampaignFilterStore } from 'store/filters/campaignFilterStore';

const CAMPAIGN_1 = {
  id: 1,
  name: 'name',
  userId: 12,
};

describe('CampaignFilterStore', () => {
  test('should load campaign by disposer - DOESNT WORK', async () => {
    const campaigns = CampaignFilterStore.create();

    campaigns.toggleCampaign(CAMPAIGN_1);
    expect(campaigns.campaign).toBeUndefined();
    try {
      expect(isObservable(campaigns.appliedIds)).toBe(true);
      campaigns.apply();
      expect(campaigns.appliedIds).toEqual([CAMPAIGN_1.id]);
    } finally {
      // campaign SHOULD be loaded
      expect(campaigns.campaign).not.toBeUndefined();
    }
  });

  test('should load campaign', async () => {
    const campaigns = CampaignFilterStore.create({
      appliedIds: [CAMPAIGN_1.id],
    });

    expect(campaigns.campaign).toBeUndefined();
    await campaigns.loadCampaign();

    expect(campaigns.campaign).not.toBeUndefined();
    expect(campaigns.campaign?.name).toEqual(CAMPAIGN_1.name);
  });
});
plicqrtu

plicqrtu1#

首先尝试将要运行的效果更改为self.loadCampaign

addDisposer(
  self,
  reaction(() => self.appliedIds, self.loadCampaign),
);

然后,在测试中,to可以创建一个针对loadCampaign操作的间谍,并确保更改appliedIds

const campaigns = CampaignFilterStore.create();
const loadCampaignSpy = jest.spyOn(campaigns, 'loadCampaign');
campaigns.setAppliedIds([1,2,3]); // appliedIds should be changed in order to run the effect defined in reaction()
expect(loadCampaignSpy).toHaveBeenCalledTimes(1);

与自动运行不同,副作用不会在初始化时运行一次,而只在数据表达式第一次返回新值之后运行。
https://mobx.js.org/reactions.html#reaction

相关问题