[英]Unit test Angular 2 service subject
我正在嘗試為一個 angular 服務編寫一個測試,該服務具有一個 Subject 屬性和一個在該主題上調用.next()
的方法。
服務如下:
@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
的參數從'test'
更改為其他任何內容,則測試總是通過事件。
我也試過用async
和fakeAsync
包裝所有東西,但結果是一樣的。
測試callNextOnSubject
是否向serviceSubjectProperty$
Subject 發送數據的正確方法是什么?
我在搜索解決方案時發現了這篇文章:
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'
,那么什么都不會“捕獲”該事件。
在調用主題后,您應該測試組件中更改的數據。 應該只測試公共變量,而不是私有或受保護; 例如:
服務:
@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);
});
});
});
到目前為止,使用jasmine'done'回調將完成這個工作,請查看以下文檔: https ://jasmine.github.io/api/edge/global(請參閱implementationCallback(doneopt))
下面是使用您的測試用例的示例:
it('callNextOnSubject() should emit data to serviceSubjectProperty$ Subject', (done) => {
inject([SubjectService], (subjectService) => {
subjectService.callNextOnSubject('test');
subjectServiceProperty$.subscribe((message) => {
expect(message).toBe('test');
done();
})
}) // function returned by 'inject' has to be invoked
});
subscribe 必須在前面,然后調用方法
it(`#${YourCompoent.prototype.yourMethod.name} subscribe must come before, and then call method`, fakeAsync( () => {
yourServiceSubject.filter$.subscribe(ev => {
expect(ev).toEqual(mock.mockFilterDefault())
});
component.sendFilterForm();
}));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.