gpt4 book ai didi

Angular 2 - 如何覆盖另一个模块中的依赖项以进行测试

转载 作者:行者123 更新时间:2023-11-28 20:51:08 25 4
gpt4 key购买 nike

我正在尝试测试我的模块中的一项服务,该服务依赖于另一个模块中的服务。另一个模块的服务、组件……通过 npm 包访问。我的公司和大多数公司一样,对将源代码放到网络上有点挑剔,所以希望我发布的内容足以获得帮助。

我要模拟的服务获取用户信息并存在于另一个模块中。我收到一条错误消息,指出此服务返回的属性未定义。我尝试使用 TestBed.overrideModule 将另一个模块中的提供程序更改为我创建的模拟版本。我在查找 overrideModule 的文档时遇到了问题,现在我已经尝试了几天,但即使在找到 overrideModule 的一些用法之后,也无法弄清楚如何实现我想要的功能。任何帮助,将不胜感激。

根据我得到的错误,我想知道是否注入(inject)了正确的依赖项,但我真的不知道如何检查。错误堆栈跟踪指向 webpack:///node_modules/@another-repo/prefs/index.js 的等价物。

代码(如果您有任何问题请告诉我,我试图删除可以识别我公司的内容):

以下是我的模块

// classa.service.ts
import { Injectable } from '@angular/core';
import { IDModel } from '@another-repo/core';
import { FormatService } from '@another-repo/prefs';
import { MyRepo } from './my-repo.service';

@Injectable()
export class ClassA {
constructor(idModel: IDModel, repo: MyRepo, formats: FormatService) {

}
doSomething() { }
}
// in my module
// my-repo.service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';

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

get(id): Observable<any> {
return this.http
.get(api(`${id}`))
.map(response => response.json());
}
}

// my-repo-service.spec.ts
//...
describe('test', () => {
let testService;
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [
HttpModule,
FooModule
],
providers: [
{ provide: RepoToMock1, useClass: MockRepoToMock1 },
MyRepo,
],
});

TestBed.overrideModule(FooModule,
{
remove: {
providers: [RepoToMock1]
},
add: {
providers: [{ provide: RepoToMock1, useClass: MockRepoToMock1 }]
}
});
});

beforeEach(() => {
testService = TestBed.get(MyRepo);
});
//...
});

这是在node_modules 的index.d.ts 文件中,我们称模块为FooModule

export class IDModel {
id: Observable<number>;
constructor(otherIdRepo: OtherIdRepo, otherType: OtherTypeModel);
}

export class FormatService {
constructor(formatModel: FormatModel, timeService: TimeService, numberService, NumberService);
}

export class FormatModel {
myFormat: Format;
constructor(repo: RepoToMock1);
}

export class Format {
branding: string;
}

export class RepoToMock1 {
constructor(http: Http);
getPrefs(): Observable<Format>;
}

export class TimeService {
constructor(formatModel: FormatModel);
}

export class NumberService {
getNumber();
}

最佳答案

正如@mgm87 所写,您应该模拟所有服务和组件以进行简单的单元测试。(作为旁注,对于组件模拟,我目前正在使用 ng-mocks 库,因为这使得模拟变得非常容易 -> 我与这个库没有任何关系)

在测试中模拟服务时,大多数时候您仍然希望能够获得有关它们的一些信息,例如它是否被调用,或者返回特定值以测试代码中的不同条件。这可以简单地用 Jasmine 和 spy 来实现。

组件的单元测试设置示例如下所示:

describe(ToTestComponent.name, () => {
let component: ToTestComponent;
let fixture: ComponentFixture<ToTestComponent>;
let mockService: any;

beforeEach(async(() => {
mockService = {
coolMethod: jasmine.createSpy('coolMethod')
};
TestBed.configureTestingModule({
declarations: [
ToTestComponent,
MockComponent(SomeChildComponent) // example of ng-mocks library
],
providers: [
{provide: RealService, useValue: mockService}
]
}).compileComponents();
}));
...

});

然后你可以简单地调用

expect(mockService.coolMethod).ToHaveBeenCalled();
// or
mockService.coolMethod.and.returnValue('I am so cool');

如您所见,在这种情况下,您甚至不必导入其他模块 (FooModule)。我使用 any 作为 mockService 的类型,否则您将必须满足类型要求。

关于Angular 2 - 如何覆盖另一个模块中的依赖项以进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46287698/

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