12

由于Angular团队不断升级/弃用Angular 2 RC版本中的内容,所以遇到此问题。Angular 2 RC4:具有依赖注入服务的单元测试组件具有自己的服务

我有一个组件具有依赖注入(DI),它实际上是一个服务(在这种情况下是UserService)。这个UserService当然有一些自己的DI。更新到Angular 2的最新RC4后,我意识到我无法再创建类似的测试。

因此,由于文档没有提及相关的东西,这里是我的代码(简化了这个问题)。

我的组件:

import { Component } from '@angular/core'; 
import { MdButton } from '@angular2-material/button'; 
import { 
    MdIcon, 
    MdIconRegistry 
} from '@angular2-material/icon'; 
import { UserService } from '../../services/index'; 

@Component({ 
    moduleId: module.id, 
    selector: 'logout-button', 
    templateUrl: 'logout-button.component.html', 
    styleUrls: ['logout-button.component.css'], 
    providers: [MdIconRegistry, UserService], 
    directives: [MdButton, MdIcon] 
}) 
export class LogoutButtonComponent { 

    constructor(public userService: UserService) {} 

    /** 
    * Call UserService and logout() method 
    */ 
    logout() { 
    this.userService.logout(); 
    } 

} 

组件的DI,UserService whic你可以看到有一些的DI(路由器,AuthHttp & HTTP):

import { Injectable } from '@angular/core'; 
import { 
    Http, 
    Headers 
} from '@angular/http'; 
import { 
    AuthHttp, 
    JwtHelper 
} from 'angular2-jwt'; 
import { Router } from '@angular/router'; 
import { UMS } from '../common/index'; 

@Injectable() 
export class UserService { 

    constructor(
    private router: Router, 
    private authHttp: AuthHttp, 
    private http: Http) { 

     this.router = router; 
     this.authHttp = authHttp; 
     this.http = http; 
    } 

    /** 
    * Logs out user 
    */ 
    public logout() { 
     this.authHttp.get(UMS.url + UMS.apis.logout) 
     .subscribe(
     data => this.logoutSuccess(), 
     err => this.logoutSuccess() 
    ); 
    } 

} 

而这里的测试对于组件:

import { By }   from '@angular/platform-browser'; 
import { DebugElement } from '@angular/core'; 

import { 
    beforeEach, 
    beforeEachProviders, 
    describe, 
    expect, 
    it, 
    inject, 
    fakeAsync, 
    TestComponentBuilder 
} from '@angular/core/testing'; 

import { AuthHttp } from 'angular2-jwt'; 
import { Router } from '@angular/router'; 
import { Http } from '@angular/http'; 
import { LogoutButtonComponent } from './logout-button.component'; 
import { UserService } from '../../services/index'; 

describe('Component: LogoutButtonComponent',() => { 



    beforeEachProviders(() => [ 
    LogoutButtonComponent, 
    UserService 
    ]); 

    it('should inject UserService', inject([LogoutButtonComponent], 
    (component: LogoutButtonComponent) => { 
     expect(component).toBeTruthy(); 
    })); 

}); 

现在不要担心它(它)。

正如你所看到的,我在beforeEachProviders上添加相关的提供者。

Error: No provider for Router! (LogoutButtonComponent -> UserService -> Router)

其中,预计让我们说:

在这种情况下,当我进行的测试,我发现了一个错误。

所以为了不要让那些我加入该服务的的DI在供应商还错误:

beforeEachProviders(() => [ 
    LogoutButtonComponent, 
    Router, 
    AuthHttp, 
    Http, 
    UserService 
    ]); 

但现在我,收到此错误:

Error: Cannot resolve all parameters for 'Router'(?, ?, ?, ?, ?, ?, ?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'Router' is decorated with Injectable.

我真的想弄清楚发生了什么,所以我在这里找到了一些相关的答案,但是所有都过时了,涵盖旧的router-deprecatedangular2/router,但两者都被弃用,并且不涵盖这种情况。

会喜欢这个的一些帮助,也许一些资源,因为我找不到有关最新版本的路由器的任何东西:"@angular/router": "3.0.0-beta.2"RC4

谢谢

更新!

我设法绕过上述两个错误,现在我可以访问该组件。这里是描述代码:

describe('Component: LogoutButtonComponent',() => { 

    let component: LogoutButtonComponent; 
    let router: any = Router; 
    let authHttp: any = AuthHttp; 
    let http: any = Http; 
    let service: any = new UserService(router, authHttp, http); 

    beforeEachProviders(() => [ 
    LogoutButtonComponent 
    ]); 

    beforeEach(() => { 
    component = new LogoutButtonComponent(service); 
    }); 

    it('should inject UserService',() => { 
    expect(component.userService).toBeTruthy(); 
    }); 

    it('should logout user',() => { 
    localStorage.setItem('token', 'FOO'); 
    component.logout(); 
    expect(localStorage.getItem('token')).toBeUndefined(); 
    }); 

}); 

但似乎即使DI服务注入和访问该服务的DI是不是。所以现在我得到这个错误:

TypeError: this.authHttp.get is not a function

任何想法?

+0

我有得到一个服务类似的问题在茉莉花测试中使用http。不幸的是,我还没有发现很多关于最新RC的这些类型测试的文档。 – jsight

+0

您是否尝试使用UserService和Router的模拟器? – tymspy

+0

@tymspy对不起,因为有很多事情要做,还没有。但是,谢谢,当我要尝试它时,我会通知你有关结果。 –

回答

3

它看起来像你遇到了依赖性循环问题,因为你的UserSerivce也需要注入AuthHttp,Http等等......如果你需要测试你的组件,它真的会干扰一次。 我的方法就是创建一个模拟UserSerivce并通过UserService.logout()方法返回期望嘲笑价值,因为你不必知道到底发生了什么在UserService,所有你需要的仅仅是一个返回值:

let MockUserService = { 
    logout() { 
    // return some value you need 
    } 
} 

然后,在测试套件中:

import { provide } from '@angular/core' 

beforeEachProviders(() => [ 
    provide(UserService, {useClass: MockUserService}) 
]) 

... detail test code here 

我希望这对你有效。 这里是一个帮助我很多的帖子: https://developers.livechatinc.com/blog/testing-angular-2-apps-dependency-injection-and-components/

0

随着RC4,在测试中使用http需要一些解决方法。也看到这个问题(应固定在RC5):

https://github.com/angular/angular/issues/9294

添加该到我的单位tests.html固定对我来说:

System.import('@angular/platform-browser/src/browser/browser_adapter').then(function(browser_adapter) { 
    browser_adapter.BrowserDomAdapter.makeCurrent(); 
}) 
相关问题