我在使用OnPush
更改检测策略测试组件时遇到问题。
测试就像这样
it('should show edit button for featured only for owners', () => {
let selector = '.edit-button';
component.isOwner = false;
fixture.detectChanges();
expect(fixture.debugElement.query(By.css(selector))).toBeFalsy();
component.isOwner = true;
fixture.detectChanges();
expect(fixture.debugElement.query(By.css(selector))).toBeTruthy();
});
如果我使用Default
策略,它会按预期工作,但使用OnPush
时,isOwner
的调用不会被detectChanges
调用。我错过了什么吗?
答案 0 :(得分:3)
你需要告诉angular你改变了组件的输入属性。在理想的世界中,您将替换
component.isOwner = false;
fixture.detectChanges();
与
component.isOwner = false;
fixture.changeDetectorRef.markForCheck();
fixture.detectChanges();
不幸的是,由于角度(https://github.com/angular/angular/issues/12313)存在错误,因此不起作用。您可以使用其中描述的解决方法之一。
答案 1 :(得分:1)
如果你查看了这个伟大的@Günter的答案angular 2 change detection and ChangeDetectionStrategy.OnPush,那么你可以使用以下事件处理程序解决它:
location.href
答案 2 :(得分:1)
类似于@michaelbromley确实公开ChangeDetectionRef的变通方法,但是由于这仅用于测试,因此我刚刚从v2.6中关闭了TypeScript errors for the next line using // @ts-ignore
标志,因此我可以离开ref private。
这可能如何工作的示例:
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { WidgetComponent } from './widget.component';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<my-widget *ngIf="widgetEnabled"></my-widget>`,
});
export class PushyComponent {
@Input() widgetEnabled = true;
constructor(private cdr: ChangeDetectorRef) {}
// methods that actually use this.cdr here...
}
TestBed.configureTestingModule({
declarations: [ PushyComponent, WidgetComponent ],
}).compileComponents();
const fixture = TestBed.createComponent(PushyComponent);
const component = fixture.componentInstance;
fixture.detectChanges();
expect(component.widgetEnabled).toBe(true);
let el = fixture.debugElement.query(By.directive(WidgetComponent));
expect(el).toBeTruthy();
component.widgetEnabled = false;
// @ts-ignore: for testing we need to access the private cdr to detect changes
component.cdr.detectChanges();
el = fixture.debugElement.query(By.directive(WidgetComponent));
expect(el).toBeFalsy();
答案 3 :(得分:0)
这个问题很容易解决... https://github.com/angular/angular/issues/12313#issuecomment-298697327
{{1}}
请记住,这种方法可能掩盖了一些变更检测问题
积分:marchitos
答案 4 :(得分:0)
有几种解决方案,但就您而言,我认为最简单的方法是将您的测试拆分为两个单独的测试。如果在每个测试中您调用 CompletableFuture<List<ResponseModels.A>> list1 = api.getListOfObjects();
CompletableFuture<List<ResponseModels.A>> list2 = api.getListOfOtherObjects();
CompletableFuture<ResponseModels.B> l = list1.thenApply(list1Objects -> list2.thenApply(list2Objects -> {
List<String> list1OfStrings = fop.stream().map(otcPaymentResultDTO -> JsonUtils.gsonFullBody.toJson(ResponseModels.B.builder() .payload(JsonUtils.gsonFullBody.toJson(list1Objects))
)).collect(Collectors.toList());
List<String> list2OfStrings = dvp.stream().map(otcDvPDTO -> JsonUtils.gsonFullBody.toJson(ResponseModels.B.builder()
.payload(JsonUtils.gsonFullBody.toJson(list2Objects)))).collect(Collectors.toList());
List<String> combinedList = Stream.concat(list1OfStrings.stream(), list2OfStrings.stream())
.collect(Collectors.toList());
return combinedList;
})));
return Flux.just(l);
函数只调用一次,一切都应该正常。
示例:
fixture.detectChanges()