由于 Angular 团队不断升级/弃用 Angular 2 RC 版本中的内容,我遇到了这个问题。
我有一个具有依赖注入(inject) (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();
}
}
Component 的 DI,UserService,如您所见,它有一些 DI(Router、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-deprecated
或 angular2/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 服务已注入(inject)并可访问,服务的 DI 也不是。所以现在我得到这个错误:
TypeError: this.authHttp.get is not a function
有什么想法吗?
最佳答案
看起来您遇到了依赖循环问题,因为您的 UserSerivce 还需要注入(inject) 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/
关于unit-testing - Angular 2 RC4 : Unit test component that has dependency injection a service that has its own,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38397245/