局限性:如果Component的changeDetection的值为ChangeDetectionStrategy.OnPush而不是Default,那么fixture.detectChanges()只有在一个test spec里第一次调用才会生效。

这是Angular一个已知的bug:https://github.com/angular/angular/issues/12313

解决方案:

beforeEach(() => {TestBed.configureTestingModule({imports: [OutletModule],declarations: [TableComponent],providers: [{ provide: TableRendererService, useClass: MockTableRendererService },],}).overrideComponent(TableComponent, {set: { changeDetection: ChangeDetectionStrategy.Default },}).compileComponents();fixture = TestBed.createComponent(TableComponent);tableComponent = fixture.componentInstance;tableRendererService = TestBed.inject(TableRendererService);fixture.detectChanges();});

ChangeDetectionStrategy.OnPush实际是一个枚举值,在Angular官网里有介绍:

enum ChangeDetectionStrategy {OnPush: 0Default: 1
}

区别

  • OnPush: 0

Use the CheckOnce strategy, meaning that automatic change detection is deactivated until reactivated by setting the strategy to Default (CheckAlways). Change detection can still be explicitly invoked. This strategy applies to all child directives and cannot be overridden.

注意:仍然可以显式触发。

  • Default: 1

Use the default CheckAlways strategy, in which change detection is automatic until explicitly deactivated.

我们甚至可以更改某个Component的change detection频率。

Detach change detector to limit how often check occurs
The following example defines a component with a large list of read-only data that is expected to change constantly, many times per second. To improve performance, we want to check and update the list less often than the changes actually occur. To do that, we detach the component’s change detector and perform an explicit local check every five seconds.

class DataListProvider {// in a real application the returned data will be different every timeget data() {return [1, 2, 3, 4, 5];}
}@Component({selector: 'giant-list',template: `<li *ngFor="let d of dataProvider.data">Data {{d}}</li>`,
})
class GiantList {constructor(private ref: ChangeDetectorRef, public dataProvider: DataListProvider) {ref.detach();setInterval(() => {this.ref.detectChanges();}, 5000);}
}@Component({selector: 'app',providers: [DataListProvider],template: `<giant-list></giant-list>`,
})
class App {}

Angular应用 changeDetection模式的设置框架代码

根据关键字ChangeDetectionStrategy搜索即可。

const createInject = makeMetadataFactory('Inject', (token) => ({ token }));
const createInjectionToken = makeMetadataFactory('InjectionToken', (desc) => ({ _desc: desc, ɵprov: undefined }));
const createAttribute = makeMetadataFactory('Attribute', (attributeName) => ({ attributeName }));
const createContentChildren = makeMetadataFactory('ContentChildren', (selector, data = {}) => (Object.assign({ selector, first: false, isViewQuery: false, descendants: false }, data)));
const createContentChild = makeMetadataFactory('ContentChild', (selector, data = {}) => (Object.assign({ selector, first: true, isViewQuery: false, descendants: true }, data)));
const createViewChildren = makeMetadataFactory('ViewChildren', (selector, data = {}) => (Object.assign({ selector, first: false, isViewQuery: true, descendants: true }, data)));
const createViewChild = makeMetadataFactory('ViewChild', (selector, data) => (Object.assign({ selector, first: true, isViewQuery: true, descendants: true }, data)));
const createDirective = makeMetadataFactory('Directive', (dir = {}) => dir);
var ViewEncapsulation;
(function (ViewEncapsulation) {ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";ViewEncapsulation[ViewEncapsulation["Native"] = 1] = "Native";ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
})(ViewEncapsulation || (ViewEncapsulation = {}));
var ChangeDetectionStrategy;
(function (ChangeDetectionStrategy) {ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
})(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));
const createComponent = makeMetadataFactory('Component', (c = {}) => (Object.assign({ changeDetection: ChangeDetectionStrategy.Default }, c)));
const createPipe = makeMetadataFactory('Pipe', (p) => (Object.assign({ pure: true }, p)));
const createInput = makeMetadataFactory('Input', (bindingPropertyName) => ({ bindingPropertyName }));
const createOutput = makeMetadataFactory('Output', (bindingPropertyName) => ({ bindingPropertyName }));
const createHostBinding = makeMetadataFactory('HostBinding', (hostPropertyName) => ({ hostPropertyName }));
const createHostListener = makeMetadataFactory('HostListener', (eventName, args) => ({ eventName, args }));
const createNgModule = makeMetadataFactory('NgModule', (ngModule) => ngModule);
const createInjectable = makeMetadataFactory('Injectable', (injectable = {}) => injectable);//告诉Angular,你正在使用自定义元素
const CUSTOM_ELEMENTS_SCHEMA = {name: 'custom-elements'
};
```![在这里插入图片描述](https://img-blog.csdnimg.cn/20210213110729716.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2kwNDI0MTY=,size_16,color_FFFFFF,t_70)

关于Angular Component changeDetection策略设置成OnPush的一个单元测试局限性相关推荐

  1. Angular Component的默认changeDetection策略

    默认策略为:ChangeDetectionStrategy.Default: 实现代码: /*** Type of the Directive metadata.** @publicApi*/ con ...

  2. Angular Component UI单元测试的隔离策略

    这是我需要进行单元测试的Component UI: 可以看到它依赖了另一个Component,其selector为cx-carousel. 因此我在单元测试实现文件里,给它创建一个mock Compo ...

  3. 深入解析Angular Component的源码示例

    本篇文章主要介绍了剖析Angular Component的源码示例,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. Web Component 定 ...

  4. 关于 Angular Component ngOnDestroy 钩子函数的调用时机

    我开发了一个 Angular Component,实现了 ngOnDestroy 钩子方法之后,没有找到其被调用的方法.查看这个StackOverflow链接后,得知无论是我刷新浏览器,还是从当前页面 ...

  5. Angular Component代码和编译后生成的JavaScript代码

    从 TypeScript 转换为 JavaScript 在这里称为编译. 在这种情况下,compiling 并不意味着创建二进制代码. 对于这种翻译,使用术语 transpilation 而不是 co ...

  6. SAP Spartacus维护CMS Component到Angular Component的源代码位置

    Spartacus界面上的banner,如下图所示,对应着HTML源代码里的cx-banner标签: cx-banner下面是cx-generic-link: 这个cx-generic-link包含一 ...

  7. Angular component的职责

    Angular Component的职责: Ideally, a component's job is to enable the user experience and nothing more. ...

  8. ft服务器设置传输协议,ft服务器设置成主动模式

    ft服务器设置成主动模式 内容精选 换一换 如果您选择使用SFS Turbo实现文件共享存储,此章节操作可跳过,您可以参见<SAP HANA用户指南>中的"格式化磁盘" ...

  9. web字体设置成平方字体_探索免费和开放的Web字体

    web字体设置成平方字体 毫无疑问,近年来,开源字体已经改变了网络的面貌. 在2010年之前,您可能会在网络浏览器中看到的唯一字体是Microsoft的通用"网络安全" 核心字体 ...

最新文章

  1. Oracle Gateway使用分享
  2. Java网络编程从入门到精通(4):DNS缓存
  3. java(9)并发编程
  4. WritableComparable排序案例(区内排序)
  5. 手把手教你用Java实现AOP
  6. 最短路 poj1125
  7. Java工作笔记-apache-tomcat-8.5.49及geoserver-2.7.5搭建
  8. 三款免费的PHP加速器:APC、eAccelerator、XCache比较
  9. 大一大学计算机课后答案,南昌大学计算机作业答案(大一)
  10. Python数据类型(3)
  11. 业务数据分析学习笔记--Lesson1
  12. 【UML】如何画好数据流图基础教程
  13. Appstore抓包获取APP历史版本
  14. 伟哥大数据入门教程一
  15. Android通知渠道
  16. drop,delete与truncate的区别
  17. 京东轮播图片的静态页面CSS3
  18. HttpRunner3使用
  19. Apache+php的安装和配置
  20. 郑刚答王峰十问:Telegram只是过渡性产品,区块链可能给社交产品带来让人兴奋的巨大改变...

热门文章

  1. 希捷操作系统SeaOS工作原理
  2. Android优化系列之apk瘦身
  3. MariaDB10 主从配置
  4. 打不开内存卡,U盘提示未格式化的3种修复及数据恢复方法
  5. 使用Redis实现分布式锁
  6. LeetCode(38): 报数
  7. css3加载ing动画
  8. CAN 屏蔽器与滤波器(过滤器)
  9. Java虚拟机执行引擎多态的实现
  10. MVC 之 属性详解