Angular 단위 테스트에서 구독 할 모의 서비스의 Subject 속성 모의

Jan 19 2021

내 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);
    });

지금 나는 모의 서비스에서 속성을 모의하기 위해 다음 두 가지 접근 방식을 사용하려고합니다.

  • 각도 단위 테스트 모의 재생 주제
  • Jasmine으로 값 속성 (메서드가 아닌)을 감시하는 방법

이제 내 테스트는 다음과 같습니다.

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 );

왜 나에게 작동하지 않습니까? 오류가 발생합니다.

정의되지 않은 '구독'속성을 읽을 수 없습니다.

답변

1 satanTime Jan 19 2021 at 13:37

때문에 작동하지 않습니다 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;

그러면 작동해야하며 약간의 조정이 필요할 수 있습니다.


고통을 피하기 위해 그러한 경우에 조롱 라이브러리를 사용하는 것이 좋습니다.

예를 들어 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.
  });
}
1 bakunet Jan 19 2021 at 14:29

나는 다음과 같은 모의 서비스를 주입하는 접근 방식으로 끝났습니다.

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);