首页 > 解决方案 > 使用 ngrx 测试服务

问题描述

我正在尝试测试具有这两个功能的 PagesService:

  setSelectedPage(selectedPage: Page): void {
    this.pagesStore.dispatch(PagesActions.setSelectedPage({ selectedPage }));
  }

  getSelectedPage(): Observable<Page> {
    return this.pagesStore.select(getSelectedPage);
  }

这是我的测试:

  it('should get selectedPage from store', () => { //Works fine
    let testSelectedPage: Page = null;
    service.getSelectedPage().subscribe(selectedPage => {
      testSelectedPage = selectedPage;
    });
    expect(testSelectedPage).toEqual(initialState.pages.selectedPage);
  });

  it('should set and get the new selectedPage from the store', () => { //Does not works
    service.setSelectedPage(initialState.pages.pages[1]);
    let testSelectedPage: Page = null;
    service.getSelectedPage().subscribe(selectedPage => {
      testSelectedPage = selectedPage;
    });
    expect(testSelectedPage).toEqual(initialState.pages.pages[1]);
  });

第一个测试工作正常,但是对于第二个测试,Karma 向我发送了一个错误,并告诉我 testSelectedPage 和 initialState.pages.pages[1] 的内容不相等。请问我错过了什么?

编辑:完整规格文件

import { TestBed } from '@angular/core/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { AppModule } from 'src/app/app.module';
import { SeoService } from 'src/app/pages/services/seo.service';
import { Page } from '../models/page.model';
import { pagesSeed, selectedPageSeed } from '../models/page.seed';
import { PagesActions } from '../store/action-types';
import { getSelectedPage } from '../store/pages.reducer';
import { PageDbService } from './page-db.service';

import { PagesService } from './pages.service';

fdescribe('PagesService', () => {
  let service: PagesService;
  const initialState = {
    pages: {
      selectedPage: selectedPageSeed,
      pages: pagesSeed,
    },
  };
  let store: MockStore;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        AppModule
      ],
      providers: [
        provideMockStore({ initialState }),
        PageDbService,
        SeoService
      ]
    });
    service = TestBed.inject(PagesService);
    store = TestBed.inject(MockStore);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
  
  it('should get selectedPage from store', (done) => {
    let testSelectedPage: Page = null;
    service.getSelectedPage().subscribe(selectedPage => {
      testSelectedPage = selectedPage;
      expect(testSelectedPage).toEqual(initialState.pages.selectedPage);
      done();
    });
  });

  it('should set and get the new selectedPage from the store', (done) => {
    service.setSelectedPage(initialState.pages.pages[1]);
    let testSelectedPage: Page = null;
    service.getSelectedPage().subscribe(selectedPage => {
      testSelectedPage = selectedPage;
      expect(testSelectedPage).toEqual(initialState.pages.pages[1]);
      done();
    });
  });
  
  // The 2 tests below Work fine but it not really test my service
  it('should get selectedPage from store', () => {
    let testSelectedPage: Page = null;
    store.select(getSelectedPage).subscribe(selectedPage => {
      testSelectedPage = selectedPage;
    });
    expect(testSelectedPage).toEqual(initialState.pages.selectedPage);
  });
  
  it('should set and get the new selectedPage from the store', () => {
    const newSelectedPage = pagesSeed[1];
    store.dispatch(PagesActions.setSelectedPage({ selectedPage: newSelectedPage }));
    store.setState({ pages: { selectedPage: newSelectedPage } });
    let testSelectedPage: Page = null;
    store.select(getSelectedPage).subscribe(selectedPage => {
      testSelectedPage = selectedPage;
    });
    expect(testSelectedPage).toEqual(newSelectedPage);
  });
});

标签: angulartypescriptunit-testingkarma-jasminengrx-store

解决方案


是否为initialState.pages.selectedPage空?

我想我知道可能出了什么问题。subscribe是异步的,这意味着它在您的expect. 我会利用done.jasmine

                                           // add done callback
  it('should get selectedPage from store', (done) => { //Works fine
    let testSelectedPage: Page = null;
    service.getSelectedPage().subscribe(selectedPage => {
      testSelectedPage = selectedPage;
      // do your assertion here
      expect(testSelectedPage).toEqual(initialState.pages.selectedPage);
      // call done to let Jasmine know you're done with the unit test
      done();
    });
    
  });

  it('should set and get the new selectedPage from the store', (done) => { //Does not works
    service.setSelectedPage(initialState.pages.pages[1]);
    let testSelectedPage: Page = null;
    service.getSelectedPage().subscribe(selectedPage => {
      testSelectedPage = selectedPage;
      expect(testSelectedPage).toEqual(initialState.pages.pages[1]);
      done();
    });
  });

推荐阅读