Verspotten einer Subject-Eigenschaft eines verspotteten Dienstes, die im Angular-Unit-Test abonniert werden soll
In meinem Angular-Unit-Test hat mein verspotteter Service zwei Eigenschaften:
public messageChange: Subject<ChatMessage> = new Subject<ChatMessage>();
public gameChange: Subject<GameState> = new Subject<GameState>();
Und in meinem SUT verwende ich sie in meinem Konstruktor:
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);
});
Im Moment versuche ich, diese beiden Ansätze zu verwenden, um Eigenschaften von verspotteten Diensten zu verspotten:
- Winkeleinheitstest Mock Replay Betreff
- So spionieren Sie eine Werteigenschaft (anstelle einer Methode) mit Jasmine aus
Jetzt sieht mein Test so aus:
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();
});
}
Also erstelle ich im Test:
Service Mock
hubServiceMock
,Fälschung
messageChange = new Subject();
,Fälschung
gameChange = new Subject();
,Ich renne für beide
.next
,und ich richte Spion für Eigenschaften ein:
spyOnProperty(hubServiceMock, 'messageChange', 'get').and.returnValue( messageChange );
spyOnProperty(hubServiceMock, 'gameChange', 'get').and.returnValue( gameChange );
Warum funktioniert es bei mir nicht? Ich erhalte eine Fehlermeldung:
Die Eigenschaft 'subscribe' von undefined kann nicht gelesen werden
Antworten
Es funktioniert nicht, weil hubServiceMock
die gefälschten Themen nicht enthalten sind messageChange
und gameChange
Sie sie vor dem Anruf festlegen müssen 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;
dann sollte es funktionieren, vielleicht sind kleine Anpassungen nötig.
Ich würde vorschlagen, für solche Fälle eine spöttische Bibliothek zu verwenden, um Schmerzen zu vermeiden.
Zum Beispiel könnte der Test mit ng-mocks folgendermaßen aussehen:
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.
});
}
Am Ende hatte ich einen Ansatz, bei dem ich verspotteten Service wie folgt einspritze:
hubServiceMock = TestBed.inject(HubConnectionService);
Dann verspotte ich meine Subject
s so:
it('Service_ShouldBeCreated', () => {
spyOn(hubServiceMock.messageChange, 'next');
spyOn(hubServiceMock.gameChange, 'next');
expect(signalrService).toBeTruthy();
});
Und in anderen Tests kann ich solche Methoden des verspotteten Dienstes anwenden:
let spyIsConnectionStarted = spyOn(hubServiceMock, 'isConnectionStarted');
spyIsConnectionStarted.and.returnValue(true);