单元测试 queryParams 订阅 (Angular5)

Posted

技术标签:

【中文标题】单元测试 queryParams 订阅 (Angular5)【英文标题】:Unit test queryParams subscription (Angular5) 【发布时间】:2018-11-03 16:53:00 【问题描述】:

我在测试 ActivatedRoute queryParams 订阅中的逻辑时遇到问题。

constructor(private router: Router, private route: ActivatedRoute, private auth: AuthService) 

ngOnInit(): void 
  this.route.queryParams.subscribe((params:any) => 
    if(params['data']) 
      this.handle(params['data']);
     else 
      if (this.auth.isAuthenticated()) 
        this.router.navigate(['/home']);
      
    
  );

我想测试:

如果在提供 params['data'] 模拟时触发 this.handle() 如果没有参数并且this.auth.isAuthenticated() 返回true,则调用this.router.navigate

我已经尝试了多种方法,但我的想法已经不多了。

我的测试文件:

describe('TestComponent', () => 
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;

  const mockService = 
    navigate: jasmine.createSpy('navigate'),
    isAuthenticated: jasmine.createSpy('isAuthenticated'),
    queryParams: jasmine.createSpy('queryParams')
  ;

  beforeEach(async(() => 
    TestBed.configureTestingModule(
      declarations: [TestComponent],
      providers: [
         provide: Router, useValue: mockService ,
         provide: ActivatedRoute, useValue: mockService ,
         provide: AuthService, useValue: mockService 
      ]
    ).compileComponents();

    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;

    mockService.navigate.calls.reset();
  ));

  it('should create the test component', () => 
    expect(component).toBeTruthy();
  );

  it('should navigate away when authenticated', () => 
    mockService.isAuthenticated.and.returnValue(true);
    mockService.queryParams.and.callFake((data, params) => new Observable(o => o.next( params:  )));
    component.ngOnInit();
    expect(mockService.navigate).toHaveBeenCalledWith(['/home']);
  );
);

但是我得到TypeError: this.route.queryParams.subscribe is not a function。我知道mockService.isAuthenticated.and.returnValue(true); 工作正常,因为在使用订阅参数之前,我在ngOnInit() 中只有这个 if 语句。

我已尝试将 mockService 更改为:

const mockService = 
  navigate: jasmine.createSpy('navigate'),
  isAuthenticated: jasmine.createSpy('isAuthenticated'),
  queryParams: 
    subscribe: jasmine.create('subscribe')
  
;

我也尝试过:

const mockService = 
  navigate: jasmine.createSpy('navigate'),
  isAuthenticated: jasmine.createSpy('isAuthenticated'),
  queryParams: 
    subscribe: Observable.of( params:  )
  
;

但没有成功,对于最后两个我得到Expected spy navigate to have been called with [ [ '/home' ] ] but it was never called.

那么有人知道如何正确测试 querParams 订阅中的逻辑吗?

【问题讨论】:

【参考方案1】:

我不能说现在回答这个问题是否为时已晚,但也许它会帮助新的谷歌员工......

我设法通过这种方式解决了这个问题:

class ActivatedRouteMock 
  queryParams = new Observable(observer => 
    const urlParams = 
      param1: 'some',
      param2: 'params'
    
    observer.next(urlParams);
    observer.complete();
  );


beforeEach(async(() => 
  TestBed.configureTestingModule(
    imports: [
      HttpClientTestingModule
    ],
    providers: [
      HttpClient,
      HttpHandler,
      ControlContainer,
      
        provide: ActivatedRoute,
        useClass: ActivatedRouteMock
      
    ]
  ).compileComponents();

  injector = getTestBed();
  httpMock = injector.get(HttpTestingController);
));

这允许您在 .subscribe(() =&gt; ) 方法中声明逻辑..

希望对你有帮助

【讨论】:

【参考方案2】:

你可以在 useValue 中使用 rxjs observable 来模拟它。

const router = 
  navigate: jasmine.createSpy('navigate')
;
beforeEach(async(() =>     
TestBed.configureTestingModule(
  imports: [
    RouterTestingModule.withRoutes([]),
    RouterTestingModule,
    PlanPrimengModule
  ],
  declarations: [YourComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  providers: [
    provideMockStore(),
    
      provide: ActivatedRoute,
      useValue: 
        queryParams: of(
          param1: "value1",
          param1: "value2"
        )
      
    ,
     provide: Router, useValue: router 
  ]
).compileComponents();   ));

【讨论】:

以上是关于单元测试 queryParams 订阅 (Angular5)的主要内容,如果未能解决你的问题,请参考以下文章

单元测试 RxJava 超时未订阅

如何在订阅Angular7单元测试用例中对代码进行单元测试

Karma 单元测试 EventEmitter 发射和订阅失败,无法读取未定义的属性“订阅”

Angularjs 基于karma和jasmine的单元测试

如何订阅角度服务单元测试中的错误案例

单元测试 - 已订阅验证Observable