繁体   English   中英

如何测试 Angular2 的 router.navigate?

[英]How to test Angular2's router.navigate?

我在其他单元测试中遇到了丢失<router-outlet>消息,但为了有一个很好的独立示例,我创建了一个 AuthGuard 来检查用户是否已登录以执行某些操作。

这是代码:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (!this.authService.isLoggedIn()) {
        this.router.navigate(['/login']);
        return false;
    }
    return true;
}

现在我想为此编写一个单元测试。

这就是我开始测试的方式:

beforeEach(() => {
    TestBed.configureTestingModule({
        imports: [
            RouterTestingModule.withRoutes([
                {
                    path: 'login',
                    component: DummyComponent
                }
            ])
        ],
        declarations: [
            DummyComponent
        ],
        providers: [
            AuthGuardService,
            {
                provide: AuthService,
                useClass: MockAuthService
            }
        ]
    });
});

我创建了一个什么都不做的 DummyComponent。 现在我的测试。 假设服务返回 false 并触发this.router.navigate(['/login'])

it('should not let users pass when not logged in', (): void => {
    expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
});

这将引发“找不到要加载的主要出口”的异常。 显然我可以使用toThrow()而不是toBe(false) ,但这似乎不是一个非常明智的解决方案。 由于我在这里测试服务,因此没有可以放置<router-outlet>标记的模板。 我可以模拟路由器并制作自己的导航功能,但是RouterTestingModule 的意义何在? 也许您甚至想检查导航是否有效。

我可以模拟路由器并制作自己的导航功能,但是RouterTestingModule 的意义何在? 也许您甚至想检查导航是否有效。

没有真正的意义。 如果他只是 auth 守卫的单元测试,那么只需模拟并监视模拟以检查它的navigate方法是否使用login参数调用

let router = {
  navigate: jasmine.createSpy('navigate')
}

{ provide: Router, useValue: router }

expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
expect(router.navigate).toHaveBeenCalledWith(['/login']);

这就是单元测试通常应该如何编写的。 为了尝试测试任何实际的真实导航,这可能属于端到端测试的范畴。

如果你想在不模拟的情况下测试路由器,你可以将它注入到你的测试中,然后直接监视那里的导航方法。 .and.stub()会成功,所以调用不会做任何事情。

describe('something that navigates', () => {
    it('should navigate', inject([Router], (router: Router) => {
      spyOn(router, 'navigate').and.stub();
      expect(authGuardService.canActivate(<any>{}, <any>{})).toBe(false);
      expect(router.navigate).toHaveBeenCalledWith(['/login']);
    }));
  });

这对我有用

describe('navigateExample', () => {
    it('navigate Example', () => {
        const routerstub: Router = TestBed.get(Router);
        spyOn(routerstub, 'navigate');
        component.navigateExample();
    });
});
     it(`editTemplate() should navigate to template build module with query params`, inject(
        [Router],
        (router: Router) => {
          let id = 25;
          spyOn(router, "navigate").and.stub();
          router.navigate(["/template-builder"], {
            queryParams: { templateId: id }
          });
          expect(router.navigate).toHaveBeenCalledWith(["/template-builder"], {
            queryParams: { templateId: id }
          });
        }
      ));

我想出了类似的东西:

describe('TestComponent', () => {
  let component: TestComponent;
  let router: Router;
  let fixture: ComponentFixture<TestComponent>;
  const routerSpy = jasmine.createSpyObj('Router', ['navigate']); // create a router spy


  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule
      ],
      declarations: [TestComponent],
      providers: [
        { provide: Router, useValue: routerSpy } // use routerSpy against Router
      ],
    }).compileComponents();
  }));

  beforeEach(() => {
    router = TestBed.inject(Router); // get instance of router 
    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it(`should navigate to 'home' page`, () => {
    component.navigateToHome(); // call router.navigate
    const spy = router.navigate as jasmine.Spy; // create the navigate spy
    const navArgs = spy.calls.first().args[0]; // get the spy values
    expect(navArgs[0]).toBe('/home');
  });
});

受角度文档的启发: https ://angular.io/guide/testing-components-scenarios#routing-component

我是单元测试 angular/javascript 应用程序的新手。 我需要一种方法来模拟(或监视)我的单元测试。 以下行是从 Experimenter 借来的,对我帮助很大!

const routerSpy = jasmine.createSpyObj('Router', ['navigate']); // 创建一个路由器间谍

我想说我不知道​​我可以用 Jasmine 做到这一点。 使用上面的那一行,我可以在该对象上创建一个间谍,并验证它是使用正确的路由值调用的。

这是一种进行单元测试的好方法,无需测试平台和围绕设置测试模块的所有仪式。 它也很棒,因为它仍然允许我拥有一个假路由器对象,而无需存根所有参数、方法等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM