H.R*_*imy 5 unit-testing typescript jestjs angular ngxs
我正在使用 ngxs 来管理我的应用程序的状态。
@State<EmployeesStateModel>({
name: 'employees',
defaults: {
// ...
}
})
@Injectable({
providedIn: 'root'
})
export class EmployeesState {
constructor(private employeesService: EmployeesService) {
}
@Action(GetEmployeesList)
async getEmployeesList(ctx: StateContext<EmployeesStateModel>, action: GetEmployeesList) {
const result = await this.employeesService
.getEmployeeListQuery(0, 10).toPromise();
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白如何使用 jest 来模拟EmployeesService测试中的依赖关系。与 NGXS 测试相关的文档也没有提供任何示例。
我刚刚开始测试角度/节点应用程序,所以我不知道我在做什么。
我按照从这个 SO 问题中学到的知识进行了以下测试。
describe('EmployeesStateService', () => {
let store: Store;
let employeesServiceStub = {} as EmployeesService;
beforeEach(() => {
employeesServiceStub = {
getEmployeeListQuery: jest.fn()
};
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
NgxsModule.forRoot([EmployeesState])
],
providers: [
{ provide: EmployeesService, useFactory: employeesServiceStub }
]
});
store = TestBed.inject(Store);
TestBed.inject(EmployeesService);
});
it('gets a list of employees', async () => {
employeesServiceStub = {
getEmployeeListQuery: jest.fn((skip, take) => [])
};
await store.dispatch(new GetEmployeesList()).toPromise();
const list = store.selectSnapshot(state => state.employees.employeesList);
expect(list).toStrictEqual([]);
});
});
Run Code Online (Sandbox Code Playgroud)
TypeError: provider.useFactory.apply is not a function当我尝试运行测试时,这会导致错误。
employeesServiceStub此外,当我在函数中设置 的值时beforeEach,它会抛出一个错误,指出我分配的值缺少实际EmployeesService. 本质上是要求我对服务进行完整的模拟实现。这对我来说效率非常低,因为在每个测试中,我需要为不同的函数定义不同的模拟实现。
TS2740: Type '{ getEmployeeListQuery: Mock ; }' is missing the following properties from type 'EmployeesService': defaultHeaders, configuration, encoder, basePath, and 8 more.
Run Code Online (Sandbox Code Playgroud)
理想情况下,在每个测试中,我应该能够为EmployeesService每个测试中的模拟函数定义不同的返回值,而不必定义该测试不需要的函数的模拟版本。
由于中的函数EmployeesService是异步函数,我也不知道如何为函数定义异步返回值。如果有人能阐明这一点,我将非常感激。
根据Mark Whitfield 给出的答案,我进行了以下更改,从而解决了我的问题。
TS2740: Type '{ getEmployeeListQuery: Mock ; }' is missing the following properties from type 'EmployeesService': defaultHeaders, configuration, encoder, basePath, and 8 more.
Run Code Online (Sandbox Code Playgroud)
您的示例中使用的提供程序定义useFactory不正确。你可以把它改成这样:
providers: [
{ provide: EmployeesService, useFactory: () => employeesServiceStub }
]
Run Code Online (Sandbox Code Playgroud)
您可以将其用于useValue您的提供程序,但这意味着您无法重新分配在 中初始化的模拟beforeEach,而必须对其进行变异:
providers: [
{ provide: EmployeesService, useValue: employeesServiceStub }
]
// then in your test...
employeesServiceStub..getEmployeeListQuery = jest.fn(....
Run Code Online (Sandbox Code Playgroud)
重新分配employeesServiceStub实际上可能仍然是您的测试的一个问题,因此您可以更改对象,或者将 TestBed 设置移到您的测试中。
注意:模拟 NGXS 状态的提供者与任何其他 Angular 服务相同。
关于您问题的第二部分,如果您说异步时指的是可观察量(我可以从您的用法中推断出),那么您可以创建一个可观察量作为结果返回。例如:
import { of } from 'rxjs';
// ...
employeesServiceStub.getEmployeeListQuery = jest.fn((skip, take) => of([]))
Run Code Online (Sandbox Code Playgroud)
附言。如果您在说异步时确实指的是承诺,那么您可以将您的方法标记为,async以便获得承诺作为结果。例如:
employeesServiceStub.getEmployeeListQuery = jest.fn(async (skip, take) => [])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
879 次 |
| 最近记录: |