如何使用 NgRX 和 Karma 正确测试 store

How to properly test store with NgRX and Karma

我正在尝试测试三件事:

  1. 查看我的 initialState 是否正在 updated/not 根据对 CourseService.emptyCourseBuffer

    的调用进行更新
  2. 查看ngrx的dispatch方法调用一次还是两次,根据1.

我已经设法让 2) 工作,但不知道如何让 1) 工作。测试 dispatch/NGRX 存储在 Angular 中的正确方法是什么?

import { TestBed } from '@angular/core/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { CourseService } from './course.service';
import { CourseContentElementType, CourseContentType } from './course-content/course-content';
import { UtilService } from '../../services/util.service';
import { CourseContentButtonEventType } from './course-content/course-content-button/course-content-button';
import { State } from '../../../builder/builder.reducer';
import { Store } from '@ngrx/store';

describe('CourseService unit tests', () => {
  let store: Store<State>;
  const initialState = {
    course: {
      modules: [
        {
          title: 'Untitled module',
          content: [
            {
              id: 1,
              uid: `${CourseContentElementType.CARD}-${UtilService.generateRandomString(10)}`,
              body: {
                text: 'Welcome',
              },
              type: CourseContentType.TEXT,
              button: [
                {
                  uid: `${CourseContentElementType.BUTTON}-${UtilService.generateRandomString(10)}`,
                  title: 'Get Started',
                  event: [
                    {
                      id: 1,
                      action: CourseContentButtonEventType.OPEN_EXTERNAL_URL,
                      value: 'https://en.wikipedia.org/wiki/Educational_technology',
                    },
                    { id: 2, action: CourseContentButtonEventType.END },
                  ],
                  isEnabled: true,
                },
              ],
            },
          ],
        },
      ],
    },
  };

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [provideMockStore({ initialState })],
    });
    store = TestBed.inject(MockStore);
  });

  describe('emptyCourseBuffer()', () => {
    it('should not set course content and empty buffer if course buffer is not populated', () => {
      const storeSpy = spyOn(store, 'dispatch').and.callThrough();
      CourseService.emptyCourseBuffer(null, store);
      expect(storeSpy).toHaveBeenCalledTimes(1);
      expect(initialState.course.modules[0].content[0].body.text).toEqual('Welcome');
    });

    it('should set course content and empty buffer if course buffer is populated', () => {
      const storeSpy = spyOn(store, 'dispatch').and.callThrough();
      CourseService.emptyCourseBuffer(initialState.course, store);
      expect(storeSpy).toHaveBeenCalledTimes(2);
      expect(initialState.course.modules[0].content[0].body.text).toEqual('Testing');
    });
  });
});

我收到以下错误 如果课程缓冲区已填充,应设置课程内容和空缓冲区

Error: Expected 'Welcome' to equal 'Testing'.

我该如何解决?

您在进行断言时似乎指的是过时的对象 (initialState)。

调用动作分派后尝试获取新状态。

试试这个:

  describe('emptyCourseBuffer()', () => {
    it('should not set course content and empty buffer if course buffer is not populated', (done) => { // add Jasmine done handler
      const storeSpy = spyOn(store, 'dispatch').and.callThrough();
      CourseService.emptyCourseBuffer(null, store);
      expect(storeSpy).toHaveBeenCalledTimes(1);
      store.subscribe(state => {
        console.log({ state }); // log it to see the structure
        expect(state.course.modules[0].content[0].body.text).toEqual('Welcome');
        done(); // call done to let Jasmine know you're done with the test
      });
    });

    it('should set course content and empty buffer if course buffer is populated', (done) => {
      const storeSpy = spyOn(store, 'dispatch').and.callThrough();
      CourseService.emptyCourseBuffer(initialState.course, store);
      expect(storeSpy).toHaveBeenCalledTimes(2);
      store.subscribe(state => {
        console.log({ state }); // log it to see the structure
        expect(state.course.modules[0].content[0].body.text).toEqual('Testing');
        done(); // call done to let Jasmine know you're done with the test
      });
    });
  });