gpt4 book ai didi

angular - 如何在 Angular 4 中使用提供程序模拟组件? - 单元测试

转载 作者:太空狗 更新时间:2023-10-29 17:07:07 24 4
gpt4 key购买 nike

我在使用 Angular 4 中的提供程序模拟组件时遇到问题。这是代码:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/core/platform-browser';
import { DebugElement } from '@angular/core';
import { FormsModule,
ReactiveFormsModule,
FormBuilder
} from '@angular/forms';
import { Router, RouterModule } from '@angular/router';
import {
Http, ConnectionBackend,
BaseRequestOptions
} from '@angular/http';
import { MockBackend, async } from '@angular/http/testing';

import { LoginComponent } from './../../../src/app/login/login.component';
import { LoginService } from './../../../src/app/login/login.service';
import { LoginComponent } from './../../../src/app/login/login.component';
import { LoggerService } from './../../../src/app/logger-service';
import { AuthService } from './../../../src/app/pages/auth.service';

describe('LoginComponent', () => {
let comp: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
let de: DebugElement;
let el: HTMLElement;

beforeEach(() => {
// implement mock
class loggerService = {

};

class loginService = {

};

class authService = {

};

class router = {

};

TestBed.configureTestingModule({
declarations: [ LoginComponent ],
imports: [
ReactiveFormsModule,
FormsModule
],
providers: [
MockBackend,
BaseRequestOptions,
AuthService,
LoginService,
LoggerService,
RouterModule,
{ provide: AuthService, useValue: authService },
{ provide: LoginService, useClass: LoginService },
{ provide: LoggerService, useValue: loggerService },
{
provide: Http, useFactory: (backend: ConnectionBackend,
defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
}, deps: [MockBackend, BaseRequestOptions]
},
{ provide: Router, useClass: router }
]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(LoginComponent);

comp = fixture.componentInstance;

comp.detectChanges();
comp.ngOnInit();

loginService = fixture.debugElement.injector.get(LoginService);
loggerService = fixture.debugElement.injector.get(LoggerService);
authService = fixture.debugElement.injector.get(AuthService);
router = fixture.debugElement.injector.get(Router);
});

});

it('should create component', async(() => {
expect(comp).toBeDefined();
}));
});

这是我的错误:

spec-bundle.js:9 Unhandled Promise rejection: No provider for AuthService! ; Zone: ProxyZone ; Task: Promise.then ; Value: Error {__zone_symbol__error: Error at Error.ZoneAwareError (http://localhost:9876/base/config/spec-bundle.js:9:3748709) a……}

知道我做错了什么吗?

提前致谢:)

最佳答案

所以我突然想到了几件事。我不确定他们是否是你的问题。

您正在尝试 stub 空类,使用它们模拟注入(inject)您的组件以代替实际服务,然后将这些注入(inject)的服务分配回 stub 变量。相反,我会尝试使用合法服务,或者将它们 stub 并获得对它们的单独引用。

在 AuthService 的情况下,如果你想提供真正的服务(即使稍后你拦截和监视它的部分),你可以只说

...
providers: [AuthService]
...

如果你想模拟它,你可以使用:

class mockAuthService{}
beforeEach(() => {
TestBed.configureTestingModule({
...
providers: [{provide: AuthService, useClass: mockAuthService}]
...

let mockAuthService;
beforeEach(() => {
mockAuthService = {}
TestBed.configureTestingModule({
...
providers: [{provide: AuthService, useValue: mockAuthService}]
...

此外,我无法仔细检查以验证这是一个问题,您是在 beforeEach 范围内而不是在其外部执行此操作(因此您以后可以引用这些变量,假设您愿意的话)。我会把它移到你的 beforeEach() 之上,就像我在上面/下面展示的那样。

这是我的意思的一个例子。

describe('LoginComponent', () => {
let comp: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
let de: DebugElement;
let el: HTMLElement;


let authServiceReference;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
imports: [
ReactiveFormsModule,
FormsModule
],
providers: [
MockBackend,
BaseRequestOptions,
AuthService,
LoginService,
LoggerService,
RouterModule,
{
provide: Http, useFactory: (backend: ConnectionBackend,
defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
}, deps: [MockBackend, BaseRequestOptions]
},
Router

]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(LoginComponent);

comp = fixture.componentInstance;

comp.detectChanges();
comp.ngOnInit();


authServiceReference = Testbed.get(AuthService); // get service you injected above

});

});

it('should create component', () => {
expect(comp).toBeDefined();
}); // this part really doesn't need to be async.

一些额外的东西(我也是新手,这些是我学到的东西)。您可能会发现在测试本身中简单地获取对注入(inject)服务的引用并不那么困惑。示例:

it('should have a service', inject([SomeService], (serviceHandle: SomeService) => {
expect(serviceHandle).toEqual(sameServiceYouTriedToGrabInInitialSetUp);
}

我希望这是有道理的,哈哈。重点是,在那里捕获它要容易得多。此外,您可以注入(inject)任意数量的服务,以获取那个特定测试的句柄。

 it('should have a service', inject([SomeService, SomeOtherService, YetOneMoreService], (serviceHandle: SomeService, otherServiceHandle: SomeOtherService, yetAnotherHandle: YetOneMoreService) => {
spyOn(serviceHandle, 'isAuthenticated').and.returnsValue(true);
spyOn(otherServiceHandle, 'getUrl').and.returnsValue(/home);
let yahSpy = spyOn(yetAnotherHandle, 'doSomething');
//code
expect (yahSpy.doSomething).toHaveBeenCalled();

}

希望这对您有所帮助。

关于angular - 如何在 Angular 4 中使用提供程序模拟组件? - 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44001255/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com