2017-07-14 138 views
1

我试图编写一个测试角度服务,它有一个主题属性和一个方法来调用.next()该主题。该服务是:单元测试Angular 2服务主题

@Injectable() 
export class SubjectService { 
    serviceSubjectProperty$: Subject<any> = new Subject(); 

    callNextOnSubject(data: any) { 
    this.serviceSubjectProperty$.next(data); 
    } 
} 

而且该服务的测试文件:

import { TestBed, inject } from '@angular/core/testing'; 

import { SubjectService } from './subject.service'; 

describe('SubjectService',() => { 

    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     providers: [ 
     SubjectService 
     ] 
    }); 
    }); 

    it('callNextOnSubject() should emit data to serviceSubjectProperty$ Subject', 
    inject([SubjectService], (subjectService) => { 
     subjectService.callNextOnSubject('test'); 

     subjectServiceProperty$.subscribe((message) => { 
     expect(message).toBe('test'); 
     }) 
    })); 
}); 

测试,如果我subjectService.callNextOnSubject从“测试”的说法改为别的始终传递事件。我也尝试用async和fakeAsync包装所有东西,但结果是一样的。

什么是测试callNextOnSubject是否将数据发送到serviceSubjectProperty $ Subject的正确方法?

+1

您应该在调用方法之前订阅*,该主题没有任何重播/缓冲区行为。 – jonrsharpe

+0

@jonrsharpe工作,谢谢。 –

+0

当您正在测试_service_时,您不应该使用角度测试基础结构。它所做的只是让你的测试代码更长,更容易出错。 –

回答

0

您应该在调用主题后测试组件中更改的数据。应该只测试公共变量,而不是私有的或受保护的; 例如:

服务:

@Injectable() 
export class SomeService { 
    onSomeSubject: Subject<any> = new Subject(); 

    someSubject(string: string) { 
     this.onSomeSubject.next(string); 
    } 
} 

组分:

export class SomeComponent { 
    @Input() string: string; 

    constructor(private service: SomeService) { 
     service.onSomeSubject.subscribe((string: string) => { 
      this.string = string; 
     }); //don't forget to add unsubscribe. 
    } 
} 

测试:

... 
describe('SomeService',() => { 
    let someService: SomeService; // import SomeService on top 
    let someComponent: SomeComponent; // import SomeService on top 

    beforeEach(() => { 
     TestBed.configureTestingModule({ 
      providers: [SomeService, SomeComponent] 
     }); 
     injector = getTestBed(); 
     someService = injector.get(SomeService); 
     someComponent = injector.get(SomeComponent); 
    }); 

    describe('someSubject',() => { 
     const string = 'someString'; 

     it('should change string in component',() => { 
      someService.someSubject(string); 
      expect(someComponent.string).tobe(string); 
     }); 
    }); 
}); 
0

我发现这篇文章,同时搜索溶液:

http://www.syntaxsuccess.com/viewarticle/unit-testing-eventemitter-in-angular-2.0

它对我来说很好(它很短,不要害怕打开它)。

我在这里粘贴它,所以也许它会帮助那些来到这个网站寻找答案。


关于这个问题问 - 我认为你需要改变:

subjectService.callNextOnSubject('test'); 

    subjectServiceProperty$.subscribe((message) => { 
    expect(message).toBe('test'); 
    }) 

subjectServiceProperty$.subscribe((message) => { 
    expect(message).toBe('test'); 
    }) 

    subjectService.callNextOnSubject('test'); 

,所以刚开始订阅,然后发出一个事件。

如果您在订阅之前发出'test',则没有任何内容会“捕捉”该事件。