Chế nhạo một thuộc tính Chủ đề của dịch vụ bị chế nhạo để được đăng ký trong thử nghiệm đơn vị Angular

Jan 19 2021

Trong thử nghiệm đơn vị Angular của tôi, dịch vụ bị chế nhạo của tôi có hai thuộc tính:

  public messageChange: Subject<ChatMessage> = new Subject<ChatMessage>();
  public gameChange: Subject<GameState> = new Subject<GameState>();

Và trong SUT của tôi, tôi sử dụng chúng trong hàm tạo của mình:

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

Hiện tại, tôi đang cố gắng sử dụng 2 cách tiếp cận này để giả lập các thuộc tính từ dịch vụ bị chế nhạo:

  • Chủ đề phát lại mô phỏng kiểm tra đơn vị góc
  • Làm thế nào để do thám Trên một thuộc tính giá trị (chứ không phải là một phương pháp) với Jasmine

Riht bây giờ thử nghiệm của tôi trông như thế này:

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

Vì vậy, trong thử nghiệm tôi tạo:

  • mô hình dịch vụ hubServiceMock,

  • giả messageChange = new Subject();,

  • giả gameChange = new Subject();,

  • tôi chạy cho cả hai .next,

  • và tôi thiết lập gián điệp cho các thuộc tính:

    spyOnProperty(hubServiceMock, 'messageChange', 'get').and.returnValue( messageChange );

    spyOnProperty(hubServiceMock, 'gameChange', 'get').and.returnValue( gameChange );

Tại sao nó không hoạt động với tôi? Tôi nhận được một lỗi:

Không thể đọc thuộc tính 'đăng ký' của không xác định

Trả lời

1 satanTime Jan 19 2021 at 13:37

Nó không hoạt động vì hubServiceMockkhông có chủ thể giả trong nó messageChangegameChange, bạn cần phải thiết lập chúng trước khi gọi 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;

sau đó nó sẽ hoạt động, có thể cần điều chỉnh nhỏ.


Tôi sẽ đề nghị sử dụng một lib chế giễu cho những trường hợp như vậy để tránh đau đớn.

Ví dụ với ng-mocks , bài kiểm tra có thể giống như sau:

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

Tôi đã kết thúc với cách tiếp cận, nơi tôi đưa ra dịch vụ chế giễu như thế này:

hubServiceMock = TestBed.inject(HubConnectionService);

Sau đó, tôi chế nhạo câu chuyện của tôi Subjectnhư thế này:

it('Service_ShouldBeCreated', () => {
    spyOn(hubServiceMock.messageChange, 'next');
    spyOn(hubServiceMock.gameChange, 'next');
    expect(signalrService).toBeTruthy();
  });

Và trong các thử nghiệm khác, tôi có thể sử dụng các phương pháp dịch vụ giả mạo như vậy:

let spyIsConnectionStarted = spyOn(hubServiceMock, 'isConnectionStarted');
    spyIsConnectionStarted.and.returnValue(true);