【问题标题】:Angular 2: Replace injected Renderer with jasmine spy object in component shallow testsAngular 2:在组件浅层测试中用茉莉间谍对象替换注入的渲染器
【发布时间】:2017-03-16 15:20:46
【问题描述】:

zippy.component.ts:

import { Component } from '@angular/core';
  import {ZippyService} from '../services/zippy.service'
  import {Renderer} from '@angular/core'

  @Component({
    selector: 'app-zippy',
    templateUrl: './zippy.component.html',
    styleUrls: ['./zippy.component.less']
  })
  export class ZippyComponent {
    doNotShow:boolean = true;

    text:string;
    constructor(private zippyService:ZippyService, private renderer:Renderer) {
      this.text = this.zippyService.getText();
    }

    toggleDisplay() {
      this.doNotShow = !this.doNotShow;
    }

  }

zippy.component.spec.ts

describe('Zippy component shallow tests', ()=>{
            let fixture:ComponentFixture<ZippyComponent>, 
                component: ZippyComponent;

            let rendererMock = jasmine.createSpyObj('rendererMock', ['myFakeMethod']);
            beforeEach(async(() => {

                TestBed.configureTestingModule({
                    declarations: [ZippyComponent, ZippyPipe],
                    providers: [
                        { provide: ZippyService, useValue: zippyServiceMock },
                        { provide: Renderer, useValue: rendererMock }
                    ],
                    schemas: [NO_ERRORS_SCHEMA]
                });

                TestBed.compileComponents().then(()=>{
                    fixture = TestBed.createComponent(ZippyComponent);
                    component    = fixture.componentInstance;
                });
            }));
       ... 
       });

使用 karma 调试创建的组件表明正在注入 zippyServiceMock 而不是 ZippyService。 但不是 rendererMock,而是注入了真正的 Renderer。 如何在测试中注入 rendererMock 而不是真实的?

【问题讨论】:

    标签: angular testing dependency-injection mocking


    【解决方案1】:

    您正在为整个模块覆盖渲染器。但是你应该只为你的组件覆盖渲染器:

        TestBed.configureTestingModule({
                    declarations: [ZippyComponent, ZippyPipe],
                    providers: [
                        { provide: ZippyService, useValue: zippyServiceMock }
                    ],
                    schemas: [NO_ERRORS_SCHEMA]
                })                
        .overrideComponent(ZippyComponent, {
             set: {
                 providers: [
                      {provide: Renderer, useValue: rendererMock}
                 ]
            }
         });
    
        TestBed.compileComponents().then(()=>{
            fixture = TestBed.createComponent(ZippyComponent);
            component    = fixture.componentInstance;
        });
    

    【讨论】:

    • 我还是得到了真正的渲染器 (DebugDomRenderer)
    【解决方案2】:

    与其模拟渲染器,不如尝试劫持它...

    这应该适用于 Angular 6+

    在您的 component.spec.ts 中

    let renderer2: Renderer2;
    ...
    beforeEach(async( () => {
       TestBed.configureTestingModule({
          ...
          providers: [Renderer2]
       }).compileComponents();
    }));
    
    beforeEach(() => {
       fixture = TestBed.createComponent(YourComponent);
       // grab the renderer
       renderer2 = fixture.componentRef.injector.get<Renderer2>(Renderer2 as Type<Renderer2>);
       // and spy on it
       spyOn(renderer2, 'addClass').and.callThrough();
       // or replace
       // spyOn(renderer2, 'addClass').and.callFake(..);
       // etc
    });
    
    it('should call renderer', () => {
        expect(renderer2.addClass).toHaveBeenCalledWith(jasmine.any(Object), 'css-class');
    });
    

    【讨论】:

      猜你喜欢
      • 2014-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-25
      相关资源
      最近更新 更多