gpt4 book ai didi

Angular 观察者模拟 Observable

转载 作者:行者123 更新时间:2023-12-05 05:07:55 25 4
gpt4 key购买 nike

我正在尝试使用 https://github.com/ngneat/spectator 编写一个(相当)复杂的测试我有一个组件,它在 ngOnInit 中有 3 个 http 服务。

其中两个很容易模拟,我可以通过两种方式来实现(我认为):

const FieldServiceMock = {
list: (categoryId: string, specificationOnly: boolean) =>
of([
{
id: 0,
canCopy: false,
categoryId: 'cameras',
dataType: 0,
display: false,
isSpecification: true,
name: 'gtin',
order: 0,
required: true,
},
]),
};

const ProductServiceMock = {
listValidatedRangeProducts: (categoryId: string) =>
of([
{
gtin: 0,
},
{
gtin: 1,
},
]),
};

let spectator: Spectator<SpecificationsSaveComponent>;
const createComponent = createComponentFactory({
component: SpecificationsSaveComponent,
imports: [],
providers: [
mockProvider(FieldService, FieldServiceMock),
mockProvider(ProductService, ProductServiceMock)
],
});

let spectator: Spectator<SpecificationsSaveComponent>;
const createComponent = createComponentFactory({
component: SpecificationsSaveComponent
});

beforeEach(() => {
spectator = createComponent();
spectator.get(FieldService).list.andReturn(of([
{
id: 0,
canCopy: false,
categoryId: 'cameras',
dataType: 0,
display: false,
isSpecification: true,
name: 'gtin',
order: 0,
required: true,
},
]));
spectator.get(ProductService).listValidatedRangeProducts.andReturn(of([
{
gtin: 0,
},
{
gtin: 1,
},
]));
});

问题是,我有另一个服务不像其他两个那样工作。该服务如下所示:

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

import { Category } from '@models';

@Injectable({
providedIn: 'root',
})
export class SelectorService {
private currentCategoriesSubject: BehaviorSubject<Category[]>;
private currentCategorySubject: BehaviorSubject<string>;

public categories: Observable<Category[]>;
public category: Observable<string>;

constructor() {
this.currentCategoriesSubject = new BehaviorSubject<Category[]>(null);
this.categories = this.currentCategoriesSubject.asObservable();

this.currentCategorySubject = new BehaviorSubject<string>(null);
this.category = this.currentCategorySubject.asObservable();
}

public setCategories(categories: Category[]): void {
if (!categories.length) return;
this.setCategory(categories[0].id);
this.currentCategoriesSubject.next(categories);
}

public setCategory(categoryId: string): void {
this.currentCategorySubject.next(categoryId);
}

public get currentCategory(): string {
return this.currentCategorySubject.value;
}

public add(category: Category) {
let categories = this.currentCategoriesSubject.value;
if (!categories) categories = [];

categories.push(category);

this.currentCategoriesSubject.next(categories);
this.currentCategorySubject.next(category.id);
}

public remove(categoryId: string) {
let categories = this.currentCategoriesSubject.value;
for (var i = 0; i < categories.length; i++) {
if (categories[i].id === categoryId) {
categories.splice(i, 1);
}
}

this.currentCategoriesSubject.next(categories);

if (!categories.length) return;

this.currentCategorySubject.next(categories[0].id);
}
}

我需要模拟的部分是公共(public)属性类别。我不确定如何去 mock 它。有人知道吗?

这是我正在测试的组件的 ngOnInit 方法:

ngOnInit() {
console.log(this.selectorService);

this.selectorService.category.subscribe(category => {
if (!category) return;

this.fieldService.list(category, false).subscribe(fields => {
let rangeFields = fields.filter(field => !field.isSpecification);
let specificationFields = fields.filter(field => field.isSpecification);

this.fields = specificationFields;

this.productService.listValidatedRangeProducts(category).subscribe(range => {
if (!range.length) return;
this.products = range;
this.range = this.productModelService.mapProducts(rangeFields, range);
this.saveForm = this.toFormGroup(range[0]);
});
});
});
}

private toFormGroup(product: any): FormGroup {
let group: any = {};

this.fields.forEach(field => {
group[field.name] = new FormControl(product[field.name]);
});

return new FormGroup(group);
}

最佳答案

我能够使用第一个选项解决这个问题:

import { Spectator, createComponentFactory, mockProvider } from '@ngneat/spectator';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { of } from 'rxjs';

import { ToastrModule } from 'ngx-toastr';
import { SharedModule } from '@shared';
import { SelectorService, ProductModelService } from '@core';
import { FieldService, ProductService } from '@services';
import { SpecificationsSaveComponent } from './specifications-save.component';

describe('SpecificationsSaveComponent', () => {
const SelectorServiceMock = {
category: of('cameras'),
};

const FieldServiceMock = {
list: (categoryId: string, specificationOnly: boolean) =>
of([
{
id: 0,
canCopy: false,
categoryId: 'cameras',
dataType: 0,
display: false,
isSpecification: true,
name: 'gtin',
order: 0,
required: true,
},
]),
};

const ProductServiceMock = {
listValidatedRangeProducts: (categoryId: string) =>
of([
{
gtin: 0,
},
{
gtin: 1,
},
]),
};

let spectator: Spectator<SpecificationsSaveComponent>;
const createComponent = createComponentFactory({
component: SpecificationsSaveComponent,
imports: [ReactiveFormsModule, HttpClientTestingModule, SharedModule, ToastrModule.forRoot()],
providers: [
mockProvider(SelectorService, SelectorServiceMock),
mockProvider(FieldService, FieldServiceMock),
mockProvider(ProductService, ProductServiceMock),
],
});

beforeEach(() => {
spectator = createComponent();
});

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

我不知道为什么第二个选项不起作用。我可以看到选择器服务具有正确的值,但由于某种原因它没有被传递给 ngOnInit 方法。有人可以解释为什么这两行不起作用吗?

beforeEach(() => {
spectator = createComponent();
spectator.get(SelectorService).category = of('cameras');
});

关于 Angular 观察者模拟 Observable<string>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58691488/

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