Vas*_*its 12 unit-testing dependency-injection jasmine typescript angular
由于Angular团队不断升级/弃用Angular 2 RC版本的东西,我遇到了这个问题.
我有一个具有依赖注入(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();
}
}
Run Code Online (Sandbox Code Playgroud)
组件的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()
);
}
}
Run Code Online (Sandbox Code Playgroud)
这是组件的测试:
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();
}));
});
Run Code Online (Sandbox Code Playgroud)
暂时不要担心(它).
正如你所看到的那样;我在上面添加了相关的提供者beforeEachProviders.
在这种情况下,我在运行测试时遇到错误:
错误:没有路由器的提供商!(LogoutButtonComponent - > UserService - > Router)
我们可以预料到这一点.
所以为了不出错,我还在服务提供商中添加了服务的DI:
beforeEachProviders(() => [
LogoutButtonComponent,
Router,
AuthHttp,
Http,
UserService
]);
Run Code Online (Sandbox Code Playgroud)
但是现在我得到了这个错误:
错误:无法解析'Router'的所有参数(?,?,?,?,?,?,?).确保所有参数都使用Inject进行修饰或具有有效的类型注释,并且"Router"使用Injectable进行修饰.
我真的想弄清楚发生了什么,所以我在这里找到了一些相关的答案,但是所有的都已经过时并且涵盖了旧的router-deprecated,angular2/router但两者都被弃用了,并没有涵盖这种情况.
我会喜欢这方面的帮助,也许还有一些资源,因为我找不到与最新版本的路由器相关的任何内容:"@angular/router": "3.0.0-beta.2"和RC4.
谢谢
UPDATE!
我设法绕过上面的两个错误,现在我可以访问该组件.这是描述代码:
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();
});
});
Run Code Online (Sandbox Code Playgroud)
但似乎即使DI服务被注入并且可访问服务的DI也不是.所以现在我收到这个错误:
TypeError:this.authHttp.get不是函数
有任何想法吗?
小智 3
看起来您遇到了依赖循环问题,因为您的 UserSerivce 还需要注入 AuthHttp、Http 等...如果您需要测试您的组件,它确实会受到干扰。我的方法是创建一个模拟 UserSerivce 并通过方法返回期望的模拟值UserService.logout(),因为您不必知道 UserService 中到底发生了什么,您需要的只是一个返回值:
let MockUserService = {
logout() {
// return some value you need
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在测试套件中:
import { provide } from '@angular/core'
beforeEachProviders(() => [
provide(UserService, {useClass: MockUserService})
])
... detail test code here
Run Code Online (Sandbox Code Playgroud)
我希望这对你有用。这是一篇对我帮助很大的帖子: https://developers.livechatinc.com/blog/testing-angular-2-apps-dependency-injection-and-components/
| 归档时间: |
|
| 查看次数: |
3215 次 |
| 最近记录: |