alt*_*ler 9 testing angular-cli angular
我在使用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();
});
Run Code Online (Sandbox Code Playgroud)
如果我使用Default策略,它会按预期工作,但OnPush更改isOwner为 时不会通过调用detectChanges. 我错过了什么吗?
小智 8
这个问题很容易解决... https://github.com/angular/angular/issues/12313#issuecomment-298697327
TestBed.configureTestingModule({
declarations: [ MyComponent ]
})
.overrideComponent(MyComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
})
.compileComponents();
Run Code Online (Sandbox Code Playgroud)
请记住,这种方法可能会掩盖一些更改检测问题
学分:马基托斯
它不起作用,因为您的装置中的changeDetectorRef与您的组件中的不同。摘自 Angular 中的问题:
“...ComponentRef 上的changeDetectorRef 指向动态创建的组件的根(主机)视图的更改检测器。然后,在主机视图内我们得到了实际的组件视图,但组件视图是 OnPush 因此我们永远不会刷新一下!” -来源
选项A。解决这个问题的一种方法是使用组件注入器来获取真正的changeDetectionRef:
describe('MyComponent', () => {
let fixture;
let component;
beforeEach(() => {
TestBed.configureTestingModule({ ... }).compileComponents();
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('does something', () => {
// set the property here
component.property = 'something';
// do a change detection on the real changeDetectionRef
fixture.componentRef.injector.get(ChangeDetectorRef).detectChanges();
expect(...).toBe(...);
});
});
Run Code Online (Sandbox Code Playgroud)
您还可以只使用到 @Input 的初始绑定(它最初触发 OnPush 策略的更改检测):
选项B1:
describe('MyComponent', () => {
let fixture;
let component;
beforeEach(() => {
TestBed.configureTestingModule({ ... }).compileComponents();
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
});
it('does something', () => {
// set the property here
component.property = 'something';
// do the first (and only) change detection here
fixture.detectChanges();
expect(...).toBe(...);
});
});
Run Code Online (Sandbox Code Playgroud)
或者例如:
选项B2:
describe('MyComponent', () => {
let fixture;
let component;
it('does something', () => {
// set the property here
setup({ property: 'something' });
expect(...).toBe(...);
});
function setup(props: { property? } = {}) {
TestBed.configureTestingModule({ ... }).compileComponents();
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
Object.getOwnPropertyNames(props).forEach((propertyName) => {
component[propertyName] = props[propertyName];
});
// do the first (and only) change detection here
fixture.detectChanges();
}
});
Run Code Online (Sandbox Code Playgroud)
您需要告诉 angular 您更改了组件的输入属性。在理想的世界中,您将替换
component.isOwner = false;
fixture.detectChanges();
Run Code Online (Sandbox Code Playgroud)
和
component.isOwner = false;
fixture.changeDetectorRef.markForCheck();
fixture.detectChanges();
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用,因为 angular 存在一个错误(https://github.com/angular/angular/issues/12313)。您可以使用那里描述的解决方法之一。
如果您查看了 @G\xc3\xbcnter\'s 的答案Angular 2 ChangeDetection 和 ChangeDetectionStrategy.OnPush,那么您可以使用事件处理程序来解决它,例如:
\n\nconst fixture = TestBed.overrideComponent(TestComponent, {set: {host: { "(click)": "dummy" }}}).createComponent(TestComponent);\n// write your test\nfixture.debugElement.triggerEventHandler(\'click\', null);\nfixture.detectChanges();\nRun Code Online (Sandbox Code Playgroud)\n\n\n
| 归档时间: |
|
| 查看次数: |
4958 次 |
| 最近记录: |