Verspotten einer Subject-Eigenschaft eines verspotteten Dienstes, die im Angular-Unit-Test abonniert werden soll

Jan 19 2021

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

1 satanTime Jan 19 2021 at 13:37

Es funktioniert nicht, weil hubServiceMockdie gefälschten Themen nicht enthalten sind messageChangeund gameChangeSie 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.
  });
}
1 bakunet Jan 19 2021 at 14:29

Am Ende hatte ich einen Ansatz, bei dem ich verspotteten Service wie folgt einspritze:

hubServiceMock = TestBed.inject(HubConnectionService);

Dann verspotte ich meine Subjects 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);