Angular 如何使用NgRX和Karma正确测试存储

Angular 如何使用NgRX和Karma正确测试存储,angular,karma-jasmine,ngrx,Angular,Karma Jasmine,Ngrx,我试图测试三件事: 查看我的初始状态是否基于调用CourseService.emptyCourseBuffer 查看是否根据1调用ngrx调度方法一次或两次 我已经设法开始工作了,但不知道该怎么做。在Angular中测试调度/NGRX存储的正确方法是什么 import { TestBed } from '@angular/core/testing'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; impo

我试图测试三件事:

  • 查看我的初始状态是否基于调用
    CourseService.emptyCourseBuffer

  • 查看是否根据1调用ngrx调度方法一次或两次

  • 我已经设法开始工作了,但不知道该怎么做。在Angular中测试调度/NGRX存储的正确方法是什么

    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');
        });
      });
    });
    

    如何修复它?

    在进行断言时,您似乎引用了一个过时的对象(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
          });
        });
      });
    
      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
          });
        });
      });