角度单元测试是否根据来自服务的数据调用组件方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了角度单元测试是否根据来自服务的数据调用组件方法相关的知识,希望对你有一定的参考价值。

我无法弄清楚如何在服务数据条件下测试组件方法是否被触发...

服务看起来像:

@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被称为。

我怎样才能解决这个问题?

提前致谢!

答案

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

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

另一答案

你设置间谍太迟了。当您将间谍安装到服务上时,它已经被构建并且已经调用了someMethod。所以在defining之后,组件称为间谍

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

Oke它是固定的!感谢@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(); 
});

以上是关于角度单元测试是否根据来自服务的数据调用组件方法的主要内容,如果未能解决你的问题,请参考以下文章

如何用玩笑模拟组件中使用的“嵌套”角度服务

角度单元测试:未调用函数

使用模拟服务时在业力测试中调用 OnInit() 后组件未定义

使用 Karma 进行角度测试

使用 Jasmine 和 Karma 进行角度单元测试时出错

测试是不是使用特定参数(来自组件)调用了 Vuex 操作