如何spyOn在构造函数中调用的方法?

时间:2018-07-23 13:37:36

标签: angular typescript unit-testing ionic-framework jasmine

我有一个离子项目,该组件的构造函数中有一个方法,该方法根据条件被调用。我正在使用Jasmine,我想spyOn该方法来检查它是否被调用。

这是组件的构造函数:

export class MyComponent {
    public test: boolean;

    constructor(public service: MyService) {
        if(test) {
            service.getX();
        }
    }
}

在我的说明中,我必须实例化组件才能spyOn方法,但是由于该方法已在构造函数中调用,因此无法正常工作。

beforeEach(() => {

    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;

});

it('Test case #1', () => {
    component.test = true;

    spyOn(component.service, 'getX'); //The method has already been called in the constructor called in beforEach above

    expect(component.service.getX).toHaveBeenCalled();
})

如何隐瞒在构造函数中调用的方法?

3 个答案:

答案 0 :(得分:1)

感谢原型继承,您可以这样做:

spyOn(MyService.prototype, 'getX');
const mock = new MyComponent({getX: () => null});
expect(MyService.prototype.getX).toHaveBeenCalled();

您也可以这样做,这更容易阅读:

const serviceMock = new MyService();
spyOn(serviceMock, 'getX');
const mock = new MyComponent(serviceMock);
expect(serviceMock.getX).toHaveBeenCalled();

请确保创建组件的模拟物以触发构造函数,因为如果不这样做,则只能使用TestBed来完成(并且间谍不会到位)。

答案 1 :(得分:0)

针对相同的问题,我刚刚实现了对构造函数中调用的方法的测试,从而激发了setTimeout中的期望:

 it('should call methodName on instance', () => {
   spyOn(instance, 'methodName').and.callThrough();   
   setTimeout(() => {
     expect(instance.methodName).toHaveBeenCalled();
   });
 });

答案 2 :(得分:0)

要在组件的构造函数中模拟服务,您需要在TestBed.createComponent

之前提供模拟

例如

beforeEach(() => {
  mockService = TestBed.get(Service); 
  mockService.getSomeValue.and.returnValue({value});
  fixture = TestBed.createComponent(MyComponent);
  component  = fixture.componentInstance;
})