5

我有以下代码...如何模拟Angular 2路线?

export class LoginComponent { 
    userName: string; 
    password: string; 
    rememberMe: boolean = false; 
    constructor(private auth: AuthenticationService, 
       private router: Router) { 
     ... 
    } 
    ... 
} 

我试图单元测试,但我的第一次尝试失败....

beforeEach(() => { 
     router = new Router(); 
     component = new LoginComponent(authService, router); 
}); 

,因为它需要params用于在路由器构造函数。 Here I saw ...

beforeEach(() => addProviders([ 
    APP_ROUTER_PROVIDERS, // must be first 
    {provide: APP_BASE_HREF, useValue: '/'}, // must be second 
    {provide: ActivatedRoute, useClass: Mock}, 
    {provide: Router, useClass: Mock} 
])); 

但我似乎并没有在我的依赖任何地方APP_ROUTER_PROVIDERSMock,所以我认为这可能是陈旧的(或者我需要依赖)。

我该如何嘲笑这件事?这对我正在进行的测试无关紧要。

回答

6

对于一个简单的例子,你可以只创建你自己的模拟和值提供它,例如:

describe('whatever',() => { 
    let mockRouter: any; 
    ... 

    beforeEach(async(() => { 
    // create your own mock 
    mockRouter = jasmine.createSpyObj('Router', ['navigate']); 

    ... 

    TestBed.configureTestingModule({ 
     declarations: [LoginComponent], 
     providers: [ 
     // provide it by value 
     { provide: Router, useValue: mockRouter }, 
     ... 
     ], 
    }).compileComponents(); 
    })); 

    ... 

}); 

这里使用了试验台的依赖注入,而不是试图去“new UP”类正在测试中。

对于上下文中的示例,参见例如, one of my projects on GitHub

+0

这与实际项目的做法有何不同(我在发表之前发布)。看来我们只需要......'TestBed.configureTestingModule({imports:[RouterTestingModule]});''''和'router = TestBed.get(Router);'?我还没有测试过,所以我不确定它是否有效。 – Jackie

+0

@Jackie你是什么意思*“实际项目”*? – jonrsharpe

+0

https://github.com/angular/angular/blob/master/modules/%40angular/router/test/router.spec.ts – Jackie

2

我接受了上述答案,因为它似乎是正确的,但是,我其实不同的方式实现它...

describe("Login Component",() => { 
    let component: LoginComponent; 
    let authService: AuthenticationService; 
    let router: Router; 

    describe("Testing the subscription happens",() => { 
     beforeEach(() => { 
      TestBed.configureTestingModule({imports: [RouterTestingModule]}); 
      router = TestBed.get(Router); 
      authService = new AuthenticationService(); 
      authService.notifications = new Subject(); 
      authService.notifications.subscribe = jasmine.createSpy("SpyToTestNotifications"); 
     }); 
     it("Make sure we try to subscribe to the auth event",() => { 
      component = new LoginComponent(authService, router); 
      expect(authService.notifications.subscribe).toHaveBeenCalled(); 
     }) 
    }); 
}); 

正如你可以看到这个只需要2线在beforeEach ...

TestBed.configureTestingModule({imports: [RouterTestingModule]}); 
router = TestBed.get(Router); 

但是,per @jonrsharpe会做很多事情,所以您无法保证可能发生的其他副作用。但它很快,很脏,它似乎“工作”

2

以下是为每个测试加载查询字符串参数的工作示例。适用于Angular 2.3。

beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ 
     MyViewerComponent, 
     ... 
     ], 
     imports: [ 
     HttpModule, 
     FormsModule, 
     RouterModule, 
     ... 
     ], 
     providers: [ 
     {provide: ActivatedRoute, useValue: {queryParams: {test: 111}}}, 
     {provide: MyService, useClass: MyMockService} 
     ] 
    }) 
     .compileComponents(); 
    }));