【问题标题】:Angular - Error running trying to mock router.eventsAngular - 尝试模拟 router.events 时出错
【发布时间】:2021-05-27 13:41:29
【问题描述】:

我正在尝试为可观察对象创建一个模拟,在本例中为 Router.events。但是我似乎遗漏了一些东西。运行 ng test 时出现错误:TypeError: this.router.events.subscribe is not a function

我创建了一个简单的服务来演示代码:

import { Injectable } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { routes } from '../constants/routes';

@Injectable({
    providedIn: 'root'
})
export class TestService {
    constructor(
        private router: Router,
    ) { }

    public result: string = null;

    init() {
        console.log('testService.init');
        let result: string = null;
        this.router.events.subscribe((event) => {
            if (event instanceof NavigationEnd) {
                if (event.url === routes.signIn) {
                    result = '1';
                } else if (event.url === routes.modules) {
                    result = '2'
                }
            }
        });

        this.result = result;

    };
}
    import { TestBed } from '@angular/core/testing';
    import { NavigationEnd, Router } from '@angular/router';
    import { of } from 'rxjs';
    import { routes } from '../constants/routes';
    import { TestService } from './test.service';
    
    describe('TestSevice', () => {
      let service: TestService;
      
    
      const router = jasmine.createSpyObj(['events']);
    
      const navigationEndMock: NavigationEnd = {
        url: null,
        id: 1,
        urlAfterRedirects: '',
        toString: () => '',
      };
    
      beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                {provide: Router, useValue: router}
              ]
        });
        service = TestBed.inject(TestService);
    
      });
    
      it('should be created', () => {
        expect(service).toBeTruthy();
      });
    
      it('if user browses to the sign in page set result to 1', () => {
        // arrange
        console.log('testSpecService');
        navigationEndMock.url = routes.signIn;
        router.events.and.returnValue(of(navigationEndMock));
    
        // act
        service.init();
    
        // assert
        expect(service.result).toBe('1')
      });
    });

任何关于我做错的提示将不胜感激。

【问题讨论】:

  • jasmine.createSpyObject 不会给你一个内部有 Observable(或任何你可以调用 subscribe 的对象)的对象。您应该手动模拟您的模拟对象,然后监视其功能。

标签: angular unit-testing rxjs jasmine observable


【解决方案1】:

在 Angular 中模拟依赖关系的最佳方法是使用测试库,例如 ng-mocks

带有解决方案的沙盒:https://codesandbox.io/s/interesting-brook-gwoow?file=/src/test.spec.ts

describe('TestSevice', () => {
  // configuring dependencies and mocks
  beforeEach(() => MockBuilder(TestService).mock(Router));

  it('if user browses to the sign in page set result to 1', () => {
    // creating a fake stream for Router.events
    const events$ = new ReplaySubject<NavigationEnd>(1);
    MockInstance(Router, 'events', events$);

    // creating the service
    const service = MockRender(TestService).point.componentInstance;

    // simulating navigation
    events$.next(MockService(NavigationEnd, {
      id: 1,
      toString: () => '',
      url: routes.signIn,
      urlAfterRedirects: '',
    }));

    // act
    service.init();

    // assert
    expect(service.result).toBe('1');

    // simulating navigation
    events$.next(MockService(NavigationEnd, {
      id: 2,
      toString: () => '',
      url: routes.modules,
      urlAfterRedirects: '',
    }));

    // act
    service.init();

    // assert
    expect(service.result).toBe('2');
  });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-24
    • 2021-11-12
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    • 2021-02-11
    • 2020-12-01
    相关资源
    最近更新 更多