【问题标题】:Angular unit test if component method is called according to a data from a service角度单元测试是否根据服务中的数据调用组件方法
【发布时间】:2017-12-29 15:00:52
【问题描述】:

我不知道如何测试组件方法是否在服务数据条件下被触发...

服务看起来像:

@Injectable()
export class SomeService {

    someData() {
        return true;
    }
}

比较:

export class SomeComponent {

    constructor(private someService: SomeService) { 

        if (this.someService.someData()) {
            this.someMethod();
        } else {
            console.log('keep kalm!');
        }
    }

    someMethod() {
        console.log('some method is fired!')
    }
}

测试:

describe('SomeComponent', () => {
    let component: SomeComponent;
    let fixture: ComponentFixture<SomeComponent>; 

    let mockSomeService = {
        someData: () => true
    }

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [SomeComponent],
            providers: [
                {
                    provide: SomeService, useValue: mockSomeService
                }
            ]
        })
        .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(SomeComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('method should be called', () => {
        spyOn(component, 'someMethod'); 

        expect(component.someMethod).toHaveBeenCalled(); 
    });
});

组件 someMethod 触发但测试失败:

预计间谍 someMethod 已被调用。

我该如何解决这个问题?

提前致谢!

【问题讨论】:

  • 测试错误是什么意思?
  • @e.m.b 预计 spy someMethod 已被调用。

标签: angular unit-testing jasmine


【解决方案1】:

好的,解决了!感谢@Supamiu 的回答

以防将来有人需要它:

将初始化移入ngOnInit,移除fixture.detectChanges();从 beforeEach 并在测试中执行它。所以:

比较:

constructor(private someService: SomeService) { }

ngOnInit() {
    if (this.someService.someData()) {
        this.someMethod();
    } else {
        console.log('keep kalm!');
    }
}

测试:

beforeEach(() => {
    fixture = TestBed.createComponent(SomeComponent);
    component = fixture.componentInstance;
    // fixture.detectChanges(); <<< Remove this
});

it('method should be called', () => {
    spyOn(component, 'someMethod'); 
    fixture.detectChanges(); // trigger ngOnInit here

    expect(component.someMethod).toHaveBeenCalled(); 
});

【讨论】:

    【解决方案2】:

    你设置间谍太晚了。当您将间谍挂载到服务上时,它已经构建完毕并且已经调用了someMethod。所以在defining之后组件调用了spy

    it('method should be called', () => {
            var spy = spyOn(component, "someMethod").and.callThrough();
            expect(component).toBeDefined();
            expect(spy);
            expect(component.someMethod).toHaveBeenCalled(); 
     });
    

    【讨论】:

      【解决方案3】:

      您必须在创建组件之前创建间谍,因为间谍无法查看过去,并且由于您的方法仅在构造函数中调用,因此在创建后未调用间谍。

      您应该将初始化移动到ngOnInit 方法或构造函数中调用的简单init() 方法,这样可以调用init 方法或ngOnInit 并检查someMethod 是否已被调用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-15
        • 1970-01-01
        • 1970-01-01
        • 2021-02-04
        • 2016-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多