gpt4 book ai didi

unit-testing - 使用 DI 进行单元测试和模拟服务

转载 作者:太空狗 更新时间:2023-10-29 18:20:21 29 4
gpt4 key购买 nike

我已经为此苦苦挣扎了一段时间,希望有人能提供帮助。我有一个使用服务获取数据的组件。我正在尝试向其添加单元测试。我的问题是测试总是失败并显示“错误:没有 Http 提供程序”。这是我的代码:

服务:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';

import { Contact } from './contact.model';

@Injectable()
export class ContactsService {
constructor(private http: Http) { }

public getContacts(): Observable<Array<Contact>> {
return this.http.get('assets/contacts.json').map(res => {
let r = res.json().Contacts;
return r;
});
}
}

组件:

import { Component, OnInit, NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Contact } from '../contact.model';
import { ContactsService } from '../contacts.service';

@Component({
selector: 'app-contacts',
templateUrl: './contacts.component.html',
styleUrls: ['./contacts.component.css'],
providers: [ContactsService]
})
export class ContactsComponent implements OnInit {

contactsAll: Array<Contact>;
contacts: Array<Contact>;

constructor(private contactsService: ContactsService) { }

ngOnInit() {
this.contactsService.getContacts().subscribe((x) => {
this.contactsAll = x;
this.contacts = this.contactsAll;
});
}

测试:

import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { Observable } from 'rxjs/Rx';

import { ContactsComponent } from './contacts.component';
import { ContactsService } from '../contacts.service';
import { Contact } from '../contact.model';

class MockContactsService extends ContactsService {

constructor() {
super(null);
}

testContacts: Array<Contact> = [
new Contact("test1 mock", 12345, 10000),
new Contact("test2 mock", 23456, 20000)
];

public getContacts(): Observable<Array<Contact>> {
return Observable.of(this.testContacts);
}
}

describe('ContactsComponent', () => {
let component: ContactsComponent;
let fixture: ComponentFixture<ContactsComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule],
declarations: [ContactsComponent],
// providers: [{ provide: ContactsService, useClass: MockContactsService }] // this is needed for the service mock
}).overrideComponent(ContactsService, {// The following is to override the provider in the @Component(...) metadata
set: {
providers: [
{ provide: ContactsService, useClass: MockContactsService },
]
}
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(ContactsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});

describe('1st test', () => {
it('true is true', () => expect(true).toBe(true));
})
});

最佳答案

让我们试试这个:

首先,将您的提供程序数组从您的组件移动到您的 NgModule。最好在模块级别提供您的服务,因为它将您的提供者从您的组件树结构中解耦(除非您特别希望每个组件都有一个单独的提供者实例,并且从您的简化用例中,没有每个组件需要一个单独的实例)。

所以,

@Component({
selector: 'app-contacts',
templateUrl: './contacts.component.html',
styleUrls: ['./contacts.component.css'],
/// providers: [ContactsService] <-- remove this line
})
export class ContactsComponent implements OnInit {
.....

并将其添加到声明您的 ContactsComponent 的 NgModule

 @NgModule({
imports: ..
declarations: ...
providers: [ContactsService] // <-- provider definition moved to here
})
export class ModuleDeclaringContactsComponent

一旦你这样做了,那么在你的测试中模拟 ContactsService 就很容易实现了。

TestBed.configureTestingModule({
imports: [FormsModule],
declarations: [ContactsComponent],
providers: [{ provide: ContactsService, useClass: MockContactsService }] // this is needed for the service mock
});

有了这些,您就可以开始了。

关于unit-testing - 使用 DI 进行单元测试和模拟服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43549861/

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