【问题标题】:Unit test queryParams subscription (Angular5)单元测试 queryParams 订阅 (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 订阅中的逻辑吗?

【问题讨论】:

    标签: javascript angular unit-testing karma-jasmine


    【解决方案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();   }));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-18
        • 2022-01-01
        • 2020-03-09
        • 2021-06-28
        • 1970-01-01
        相关资源
        最近更新 更多