【问题标题】:How to cover the RXJS pipe function in Jasmine?如何覆盖 Jasmine 中的 RXJS 管道功能?
【发布时间】:2020-06-26 13:30:15
【问题描述】:

我想在Angular/Jasmine中介绍RXJS的管道功能。

我收到此错误:

TypeError: this.element.children.pipe is not a function

代码:

ngOnInit() {
    this.element.children.pipe(
      mapObservableArray((children: ObservableTree<ItemModel>) => children.value.properties))
        .subscribe((props: Properties[]) => {
        // do something with the props or children
        this.childrenElements = props as any;
    });
}

这确保我可以检索孩子的值并将其保存在 this.childrenElements 上。

.spec 文件:

import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { myComponent } from './my.component';

describe('myComponent', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [CommonModule],
      declarations: [myComponent],
      providers: [],
      schemas: [NO_ERRORS_SCHEMA],
    }).compileComponents();
  });

  it('should create the component', async () => {
    const fixture = TestBed.createComponent(myComponent);
    const componentInst = fixture.componentInstance;

    componentInst.childrenElements = [
      { name: 'name1' },
      { name: 'name2' }
    ];

    // when
    componentInst.ngOnInit();

    // then
    expect(componentInst).toBeDefined();
  });
});

尝试存根: spyOn(componentInst.element.children, 'pipe').and.stub();

但这没有帮助。

this.element.children:

如何覆盖我的这部分代码?

【问题讨论】:

    标签: angular unit-testing rxjs jasmine


    【解决方案1】:

    您必须删除 element.children 的可观察数据(无论它是什么)。

    这是我第一次见到mapObservableArray,所以我认为那是内部运营商。

    试试:

    import { of } from 'rxjs';
    .....
     it('should create the component', async () => {
        const fixture = TestBed.createComponent(myComponent);
        const componentInst = fixture.componentInstance;
    
        (componentInst as any).element = {
          children: of(/* mock how the children property should look like */);
        };
    
        // when
        // componentInst.ngOnInit();
        // don't call ngOnInit directly, the first detectChanges will call ngOnInit for you
        fixture.detectChanges();
    
        // then
        expect(componentInst).toBeDefined();
      });
    

    如果 element.children 是从另一个 observable 派生的,您必须像我展示的那样模拟另一个 observable,它应该可以很好地流动。

    编辑 尝试将它分配给我上面的对象。如果元素是只读的或私有的,那么将很难模拟。尝试做(componentInst as any) 虽然我不认为这是最好的做法。出于测试目的,可能会删除它的只读或私有方面。你发给我的截图是被包装的 observable,你必须把未包装的值放在 of 里面。

    【讨论】:

    • 你能举一个如何模拟的例子吗?我在第一条消息中添加了 element.children 的屏幕截图。当我尝试模拟时,我得到(property) ObservableTree&lt;ItemModel&gt;.children: Observable&lt;ObservableTree&lt;ItemModel&gt;[]&gt; The children of this node Cannot assign to 'children' because it is a read-only property.ts(2540)
    • 我添加了一个编辑。 this.element 是什么?它是一个对象吗?
    • this.element 中有 observables。现在使用您更改的代码,测试在管道内。但是这次我在道具上遇到了错误。 Uncaught TypeError: Cannot read property 'properties' of undefined thrown
    • properties 是否存在于element 中?如果是这样,你将不得不以同样的方式模拟它。
    猜你喜欢
    • 2019-06-30
    • 2019-06-13
    • 2019-09-13
    • 2020-05-12
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多