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(); 
    }));