![](/img/trans.png)
[英]Unit Testing Angular components with rxjs Subjects using Jasmine
[英]Angular, Subjects Unit Testing
我們最近在 Angular 7 中主要基於這個解決方案實現了一個消息服務,但我們堅持單元測試實現。
我們有這樣的服務:
@Injectable()
export class MessageService {
private subject = new Subject<any>();
sendMessage(message: MessageInput) {
this.subject.next(message);
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
我們有這個實現,監聽另一個組件發送的消息:
ngOnInit() {
this.subscription = this.messageService.getMessage().subscribe(
(message: MessageInput) => {
if (message) {
.....
}
}, () => {
.....
}
)};
我們想對我們的實現進行單元測試,但我們無法模擬消息的發送和接收。 我們正在嘗試這個:
beforeEach(() => {
TestBed.configureTestingModule({
schemas: [NO_ERRORS_SCHEMA],
declarations: [...],
providers: [
...
MessageService
],
imports: [...]
});
fixture = TestBed.createComponent(...);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('makes ngOnInit expected calls', () => {
const messageService: MessageService = fixture.debugElement.injector.get(
MessageService
);
component.ngOnInit();
expect(component.subscription).toBeDefined();
const message: MessageInput = {text: TypeMessage...., data: '...'};
const nextSpy = spyOn(messageService.getMessage(), 'subscribe');
messageService.sendMessage(message);
expect(nextSpy).toHaveBeenCalled();
});
我們在那里迷路了,有人可以幫助我們嗎? 謝謝!
如果您查看源代碼,您會注意到每當asObservable
被調用時,都會創建並返回一個新對象。 因此,您基本上是在監視錯誤的對象。
您可以通過以下重構來解決這個問題:
@Injectable()
export class MessageService {
private subject = new Subject<any>();
public readonly messages$ = this.subject.asObservable();
sendMessage(message: MessageInput) {
this.subject.next(message);
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.messages$;
}
}
並按如下方式更新您的測試:
it('makes ngOnInit expected calls', () => {
const messageService: MessageService = fixture.debugElement.injector.get(MessageService);
const nextSpy = spyOn(messageService.messages$, 'subscribe');
component.ngOnInit();
messageService.sendMessage(message);
expect(component.subscription).toBeDefined();
expect(nextSpy).toHaveBeenCalled();
});
如果您的目標只是模擬消息(您的服務)的發送/接收,您可以只對消息服務使用模擬。
mockSubject = new Subject();
mockSubject =next({'Message'})
mockMessangerService= {
getMessage: jasmine.createSpy('openConfirmModal').and.returnValue(mockSubject.asObservable()),
sendMessage: jasmine.createSpy('sendMessage')
}
TestBed.configureTestingModule({
...
}).overrideComponent(*component*,
{
set: { providers: [{provide: MessageService , useValue: mockMessangerService}]}
}....
然后你可以測試你的間諜
expect(mockMessangerService.getMessage).toHaveBeenCalled();
expect(mockMessangerService.sendMessage).toHaveBeenCalledWith('Message');
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.