如何在Jasmine和Angular中测试ngOnInit的代码逻辑

如何在Jasmine和Angular中测试ngOnInit的代码逻辑,jasmine,angular6,angular-test,Jasmine,Angular6,Angular Test,我的组件在ngOnInit中的route中查找是否存在参数。如果参数不存在,则显示错误。我想测试一下这个逻辑 ngOnInit() { this.id = this.route.snapshot.paramMap.get("id"); if(this.id != null) { ... } else{ console.log("didn't get id from the route"); this.showDialog(...); }

我的组件在
ngOnInit
中的
route
中查找是否存在参数。如果参数不存在,则显示错误。我想测试一下这个逻辑

ngOnInit() {
    this.id = this.route.snapshot.paramMap.get("id");
    if(this.id != null) {
...    } else{
      console.log("didn't get id from the route");
      this.showDialog(...);
    }
  }
我编写了以下规范。在规范中,
route

 beforeEach(async() => {

    fixture = TestBed.createComponent(QuestionDetailsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

fit('should show error if question details of a question can\'t be retrieved', () => {
    spyOn(component,'showDialog');
    expect(componetn.showDialog).toHaveBeenCalled();
  });
但我的测试用例失败,原因是
预期spy showDialog已被调用

我认为问题在于,在调用
组件之前创建组件时,会调用
showDialog


如何在
ngOnInit
中测试逻辑?我需要组件才能测试它(即调用
it
),我想测试在创建组件时执行的逻辑。

要测试ngOnInit方法,您只需要调用它:

component.ngOnInit();
并且可以监视路由值:

spyOn(component.route.snapshot.paramMap,"get").and.returnValue("some_id");
此外,还可以更改返回值。例如:

fit("should ...", () => {
  let mock_id = null;
  spyOn(component,"showDialog");

  spyOn(component.route.snapshot.paramMap,"get").and.callFake(() => {
      return mock_id;
  });

  component.ngOnInit();
  expect(componetn.showDialog).toHaveBeenCalled();
  expect(componetn.showDialog).toHaveBeenCalledTimes(1);

  mock_id = "some_value";
  component.ngOnInit();
  expect(...).to..
  ...
  expect(componetn.showDialog).toHaveBeenCalledTimes(1);

  mock_id = "another_value";
  component.ngOnInit();
  expect(...).to..
  ...
  expect(componetn.showDialog).toHaveBeenCalledTimes(1);
});

要测试ngOnInit方法,只需调用它:

component.ngOnInit();
并且可以监视路由值:

spyOn(component.route.snapshot.paramMap,"get").and.returnValue("some_id");
此外,还可以更改返回值。例如:

fit("should ...", () => {
  let mock_id = null;
  spyOn(component,"showDialog");

  spyOn(component.route.snapshot.paramMap,"get").and.callFake(() => {
      return mock_id;
  });

  component.ngOnInit();
  expect(componetn.showDialog).toHaveBeenCalled();
  expect(componetn.showDialog).toHaveBeenCalledTimes(1);

  mock_id = "some_value";
  component.ngOnInit();
  expect(...).to..
  ...
  expect(componetn.showDialog).toHaveBeenCalledTimes(1);

  mock_id = "another_value";
  component.ngOnInit();
  expect(...).to..
  ...
  expect(componetn.showDialog).toHaveBeenCalledTimes(1);
});

非常感谢。您关于spyOn(component.route.snapshot.paramMap,“get”)和.returnValue(“some_id”)的说明也解决了这个问题。如果你把这个作为答案写在那里,我很乐意接受。我注意到你的解决方案中有一个潜在的问题。我必须将
route
公开,以便我可以在规范中访问它。有其他选择吗?没有,没有必要将
route
公开。我认为“困扰”的是编辑。对我来说,忽略这一点的最快方法是:
spyOn(component[“route”].snapshot.paramMap,“get”).and.returnValue(“some_id”)
非常感谢。您关于spyOn(component.route.snapshot.paramMap,“get”)和.returnValue(“some_id”)的说明也解决了这个问题。如果你把这个作为答案写在那里,我很乐意接受。我注意到你的解决方案中有一个潜在的问题。我必须将
route
公开,以便我可以在规范中访问它。有其他选择吗?没有,没有必要将
route
公开。我认为“困扰”的是编辑。对我来说,忽略这一点的最快方法(我使用VSCode)是:
spyOn(component[“route”].snapshot.paramMap,“get”).and.returnValue(“some_id”)