[英]Mocking a Subject property of mocked service to be subscribed in the Angular unit test
在我的 Angular 單元測試中,我的模擬服務有兩個屬性:
public messageChange: Subject<ChatMessage> = new Subject<ChatMessage>();
public gameChange: Subject<GameState> = new Subject<GameState>();
在我的 SUT 中,我在構造函數中使用它們:
this._subChat = this.hub.messageChange.subscribe((message: ChatMessage) => {
this.message = message;
this.messageChange.next(this.message);
});
this._subGame = this.hub.gameChange.subscribe((game: GameState) => {
this.game.setGame(game);
});
現在我正在嘗試使用這兩種方法來模擬來自模擬服務的屬性:
現在我的測試看起來像這樣:
describe('SignalRService', () => {
let signalrService: SignalRService;
const hubServiceMock = jasmine.createSpyObj('HubConnectionService', [
'isConnectionStarted',
]);
const messageChange = new Subject();
const gameChange = new Subject();
beforeEach(() => {
signalrService = new SignalRService(
hubServiceMock
);
let msg = {} as ChatMessage;
let gam = {} as GameState;
messageChange.next(msg);
gameChange.next(gam);
});
it('Service_ShouldBeCreated', () => {
spyOnProperty(hubServiceMock, 'messageChange', 'get').and.returnValue(
messageChange
);
spyOnProperty(hubServiceMock, 'gameChange', 'get').and.returnValue(
gameChange
);
expect(signalrService).toBeTruthy();
});
}
所以在我創建的測試中:
服務模擬hubServiceMock
,
假messageChange = new Subject();
,
假gameChange = new Subject();
,
我為兩個.next
競選,
我為屬性設置了間諜:
spyOnProperty(hubServiceMock, 'messageChange', 'get').and.returnValue( messageChange );
spyOnProperty(hubServiceMock, 'gameChange', 'get').and.returnValue( gameChange );
為什么它對我不起作用? 我收到一個錯誤:
無法讀取未定義的屬性“訂閱”
它不起作用,因為hubServiceMock
在其messageChange
和gameChange
中沒有虛假主題,您需要在調用new SignalRService(hubServiceMock)
之前設置它們。
const hubServiceMock = jasmine.createSpyObj('HubConnectionService', [
'isConnectionStarted',
]);
const messageChange = new Subject();
const gameChange = new Subject();
// add this
hubServiceMock.messageChange = messageChange;
hubServiceMock.gameChange = gameChange;
那么它應該可以工作,也許需要進行一些小的調整。
我建議在這種情況下使用 mocking lib 以避免疼痛。
例如使用ng-mocks ,測試可能如下所示:
describe('SignalRService', () => {
beforeEach(() => MockBuilder(SignalRService, ITS_MODULE));
const hubServiceMock = {
messageChange: new Subject(),
gameChange: new Subject(),
};
beforeEach(() => MockInstance(HubConnectionService, hubServiceMock));
it('Service_ShouldBeCreated', () => {
const signalrService = MockRender(SignalRService).point.componentInstance;
expect(signalrService).toBeTruthy();
hubServiceMock.messageChange.next({});
hubServiceMock.gameChange.next({});
// next assertions.
});
}
我最終采用了方法,在其中注入了這樣的模擬服務:
hubServiceMock = TestBed.inject(HubConnectionService);
然后我像這樣模擬我的Subject
:
it('Service_ShouldBeCreated', () => {
spyOn(hubServiceMock.messageChange, 'next');
spyOn(hubServiceMock.gameChange, 'next');
expect(signalrService).toBeTruthy();
});
在其他測試中,我可以使用這樣的模擬服務方法:
let spyIsConnectionStarted = spyOn(hubServiceMock, 'isConnectionStarted');
spyIsConnectionStarted.and.returnValue(true);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.