如何解决如何在玩笑单元测试中模拟私有 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();
// ...
}
}
问题
我不明白如何在测试中使用 jest 来模拟 EmployeesService
依赖项。与 NGXS 测试相关的文档也没有提供任何示例。
我刚刚开始测试 angular/node 应用程序,所以我不知道我在做什么。
我按照从 this SO question 学到的知识进行了以下测试。
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([]);
});
});
当我尝试运行测试时,这会导致错误 TypeError: provider.useFactory.apply is not a function
。
此外,当我在 employeesServiceStub
函数中设置 beforeEach
的值时,它会引发错误,指出我分配的值缺少实际 {{1} 中的其余属性}.本质上要求我对服务进行完整的模拟实现。这对我来说是非常低效的,因为在每次测试中,我都需要为不同的函数定义不同的模拟实现。
EmployeesService
理想情况下,在每个测试中,我应该能够在每个测试中为 TS2740: Type '{ getEmployeeListQuery: Mock ; }' is missing the following properties from type 'EmployeesService': defaultHeaders,configuration,encoder,basePath,and 8 more.
的模拟函数定义不同的返回值,而不必定义该测试不需要的函数的模拟版本.
由于 EmployeesService
中的函数是异步函数,我也不知道如何为函数定义异步返回值。如果有人能对此有所了解,我将不胜感激。
最终解决方案
基于 answer given by Mark Whitfield,我进行了以下更改以解决我的问题。
EmployeesService
解决方法
您的示例中使用 useFactory
的提供程序定义不正确。
你可以把它改成这样:
providers: [
{ provide: EmployeesService,useFactory: () => employeesServiceStub }
]
您可以将 useValue
用于您的提供者,但这意味着您无法重新分配您在 beforeEach
中初始化的模拟,而是必须对其进行变异:
providers: [
{ provide: EmployeesService,useValue: employeesServiceStub }
]
// then in your test...
employeesServiceStub..getEmployeeListQuery = jest.fn(....
employeesServiceStub
的重新分配实际上可能仍然是您的测试的问题,因此您可以改为改变对象,或将 TestBed 设置移动到您的测试中。
注意:模拟 NGXS 状态的提供者与任何其他 Angular 服务相同。
关于您问题的第二部分,如果您在说 async 时指的是 observable(我可以从您的用法中推断出),那么您可以创建一个 observable 作为结果返回。例如:
import { of } from 'rxjs';
// ...
employeesServiceStub.getEmployeeListQuery = jest.fn((skip,take) => of([]))
附注。如果您在说 async 时确实指的是承诺,那么您只需将您的方法标记为 async
以获得承诺作为结果。例如:
employeesServiceStub.getEmployeeListQuery = jest.fn(async (skip,take) => [])
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。