我正在单元测试Angular 12组件。组件在初始化时从服务中获取可观察的返回(参见下面的thing.service.ts
)。它被分配给一个主题,该主题通过async
管道显示在html模板中(参见下面的app.component.html
)。
AppComponent.ts
export class AppComponent {
public errorObjectSubject = null;
public thingsSubject: Subject<Array<IThing>> = new Subject();
constructor(private readonly _service: ThingService) {
this._getAllProducts();
}
private async _getAllProducts(): Promise<void> {
this._service.getAllObservableAsync()
.pipe(take(1),
catchError(err => {
this.errorObjectSubject = err;
return throwError(err);
})
).subscribe(result => { this.thingsSubject.next(result) });
}
}
模板订阅公共内容主题:主题
app.component.html
<div>
<app-thing *ngFor="let thing of thingsSubject | async" [thing]="thing"></app-thing>
</div>
thing.service.ts
constructor(private readonly _http: HttpClient) { }
public getAllObservableAsync(): Observable<Array<IThing>> {
return this._http.get<Array<IThing>>('https://jsonplaceholder.typicode.com/todos'); }
这是测试设置。
app.component.spec.ts
describe('AppComponent', () => {
let component: AppComponent,
fixture: ComponentFixture<AppComponent>,
dependencies: { thingService: ThingServiceStub };
function getThings(): Array<DebugElement> {
return fixture.debugElement.queryAll(By.directive(ThingComponentStub));
}
beforeEach(async () => {
dependencies = {
thingService: new ThingServiceStub()
};
await TestBed.configureTestingModule({
declarations: [AppComponent, ThingComponentStub],
providers: [
{ provide: ThingService, useValue: dependencies.thingService }
]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
//fixture.detectChanges();
});
describe('on initialisation', () => {
let getThingsSubject: Subject<Array<IThing>>;
beforeEach(() => {
getThingsSubject = new Subject();
(dependencies.thingService
.getAllObservableAsync as jasmine.Spy).and.returnValue(
getThingsSubject.asObservable()
);
fixture.detectChanges();
});
it('should fetch all of the things', () => {
//fixture.detectChanges();
expect(
dependencies.thingService.getAllObservableAsync
).toHaveBeenCalledWith();
});
describe('when the things have been fetched', () => {
beforeEach(fakeAsync(() => {
getThingsSubject.next()
// getThingsSubject.next([
// {
// userId: 1,
// id: 1,
// title: 'string',
// completed: 'string'
// }
// ]);
//getThingsSubject.pipe().subscribe()
tick();
fixture.detectChanges();
}));
it('should display the things', () => {
expect(getThings()[0].componentInstance.product).toEqual({
name: 'product',
number: '1'
});
});
});
});
});
thing.service.stub.ts
export class ProductServiceStub {
public getAllObservableAsync: jasmine.Spy = jasmine.createSpy('getAllObservableAsync');
}
我正在尝试在模板中填充内容(
IThing[]
)之后测试它的工作方式。我有一个合格的规范,称模拟可观察:
it('should fetch all of the things', () => {
expect(
dependencies.thingService.getAllObservableAsync
).toHaveBeenCalledWith();
});
然而,当我尝试测试模板时,我点击了“Error:Uncaught(in promise):TypeError:cannotreadproperty'pipe'of undefine:
descripe('当东西被提取时'
)。
我不太清楚是什么问题。这是我设置订阅主题的方式吗?还是变化检测?
我认为你称呼事物的顺序可能是个问题。
试试这个:
describe('AppComponent', () => {
let component: AppComponent,
fixture: ComponentFixture<AppComponent>,
dependencies: { thingService: ThingServiceStub };
function getThings(): Array<DebugElement> {
return fixture.debugElement.queryAll(By.directive(ThingComponentStub));
}
beforeEach(async () => {
dependencies = {
thingService: new ThingServiceStub()
};
await TestBed.configureTestingModule({
declarations: [AppComponent, ThingComponentStub],
providers: [
{ provide: ThingService, useValue: dependencies.thingService }
]
}).compileComponents();
});
beforeEach(() => {
// !! This (.createComponent) is when the constructor is called, so mock the observable
// before here and change the subject to a BehaviorSubject.
// Maybe subject will work as well.
let getThingsSubject = new BehaviorSubject([{ name: 'product', number: '1' }]);
(dependencies.thingService.getAllObservableAsync as jasmine.Spy).and.returnValue(
getThingsSubject.asObservable()
);
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
describe('on initialisation', () => {
let getThingsSubject: Subject<Array<IThing>>;
it('should fetch all of the things', () => {
expect(
dependencies.thingService.getAllObservableAsync
).toHaveBeenCalledWith();
});
describe('when the things have been fetched', () => {
// maybe tick and fakeAsync are not needed but `fixture.detectChanges` is
beforeEach(fakeAsync(() => {
tick();
fixture.detectChanges();
}));
it('should display the things', () => {
// !! Add this log for debugging
console.log(fixture.nativeElement);
expect(getThings()[0].componentInstance.product).toEqual({
name: 'product',
number: '1'
});
});
});
});
});
问题内容: 给定汽车清单(),我可以这样做: 有没有办法我可以从一个到一个序列? 像没有参数的东西 问题答案: 您可以这样映射到: 请注意,flatMapping可能不会保留源可观察的顺序。如果订单对您很重要,请使用。
学习角得到服务和组件和可观察性。 我正在尝试在我的演示应用程序中实现暗模式。该控件由一个服务完成,该服务根据浏览器默认值(如果找到)设置暗主题。 它在应用程序组件中初始化,以便以后在应用程序中放置控制开关。 暗模式从布尔值开始工作,因此为true或false。据我所知,使用一个可观察对象是不够的,因为我希望多个订阅者都以两种方式绑定到订阅,每种方式在服务中切换这些可观察对象。到目前为止,我很肯定这
问题内容: 我一直在阅读Observer模式,以保持UI处于最新状态,但仍然看不到它的用途。即使在我的特定对象中通知了我的MainActivity然后运行update();方法我仍然无法使用Pet对象来获取更新值,因为该对象是在Oncreate中创建的…而我只是无法创建新对象,因为那时变量会有所不同..这是我的实施,它似乎不起作用。 观察者/ MainActivity 可观察/宠物 问题答案: 首
为什么我会得到nullPointerException尽管我删除了observer并使用了mLiveData.getValue()和assertNotNull(mLiveData)它工作得很好? 和错误
我试图理解当我使用 在或之后,在我使用时返回true 我知道是一次性的。isDisposed()返回false。有人能解释一下到底发生了什么吗?。我理解一个写得很好的观察。create不能在onComplete()或onError()之后发出项。
我需要用jasmine对一些DOM操作函数进行单元测试(目前我在浏览器和Karma中运行测试) 我想知道最好的方法是什么? 例如,我可以模拟和存根窗口,记录对象和spyOn的几个函数。但这看起来并不是一个简单的解决方案,所以我要问这个问题! 或者有没有更好的方法(也许不用茉莉花)来做到这一点? 非常感谢