簡體   English   中英

在模擬 observable 時調用 subscribe 中的測試方法

[英]Testing method inside a subscribe is called, when mocking an observable

在我的測試“應該發出動作完成”中,我試圖測試在調用“OnBookActionClick”方法時調用“bookActionCompleted”的發出函數。 這個發射函數在一個方法中調用,該方法傳遞給從我的服務方法返回的 void observable 的訂閱函數。

不幸的是,從來沒有通過運行我的測試調用傳遞到組件上的 subscribe 方法的代碼。 在這些測試中,我通過返回 of() 來嘲笑“publishBook”和“unpublishBook”的響應,我懷疑這可能是問題的原因,但是我完全不知道如何進行。

成分

import { Component, EventEmitter, Input, Output } from '@angular/core';

import { Library, LibraryBook } from '../../models';
import { LibraryService } from '../../services';

@Component({
    selector: 'librarycatalogue-books-view',
    templateUrl: './books-view.component.html',
    styleUrls: ['./books-view.component.scss']
})
export class BooksViewComponent {
    @Input() library!: Library;
    @Output() bookActionCompleted = new EventEmitter();

    constructor(private libraryService: LibraryService) {}

    onBookActionClick(book: LibraryBook) {
        const action = book.isPublished
            ? this.libraryService.unpublishBook(this.library.libraryId, book.bookId)
            : this.libraryService.publishBook(this.library.libraryId, book.bookId);
        action.subscribe(() => {
            this.bookActionCompleted.emit()
        });
    }
}

服務方法(正在被模擬)

publishBook(libraryId: string, bookId: string): Observable<void> {
    return this.http.put<void>(`${this.baseUrl}/${libraryId}/book/${bookId}/publish`, null);
}

unpublishBook(libraryId: string, bookId: string): Observable<void> {
    return this.http.put<void>(`${this.baseUrl}/${libaryId}/book/${bookId}/unpublish`, null);
}

測試

import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { createSpyObject, SpyObject } from '@ngneat/spectator/jest';
import { of } from 'rxjs';

import { Library, LibraryBook } from '../../models';
import { LibraryService } from '../../services';
import { BooksViewComponent } from './books-view.component';

describe('BooksViewComponent', () => {
  let component: BooksViewComponent;
  let fixture: ComponentFixture<BooksViewComponent>;
  let libraryService: SpyObject<LibraryService>;

  beforeEach(async () => {

    libraryService = createSpyObject(LibraryService);
    libraryService.publishBook.mockReturnValue(of());
    libraryService.unpublishBook.mockReturnValue(of());

    await TestBed.configureTestingModule({
      declarations: [ BooksViewComponent ],
      imports: [HttpClientTestingModule],
      providers: [
        { provide: LibraryService, useValue: libraryService }
      ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(BooksViewComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  describe('On book action click', () => {
    let library: Library;
    let publishedBook: LibraryBook;
    let unpublishedBook: LibraryBook;

    beforeEach(() => {
      library = {  libraryId: '1',
                name: 'New York Library',
                books: [
                { book: 1, bookId: '1', isPublished: false},
                { book: 2, bookId: '2', isPublished: true }
              ]
            };

            publishedBook = library.books.filter(x => x.isPublished)[0];
            unpublishedBook = library.books.filter(x => !x.isPublished)[0];

      component.library = library;
      jest.spyOn(component.bookActionCompleted, 'emit');
    });
    
    describe('If item is published', () => {
      it('should be unpublished', () => {
        component.onBookActionClick(publishedBook);

        expect(libraryService.unpublishBook).toHaveBeenCalled();
      })

      it('should emit action complete', () => {
        component.onBookActionClick(publishedBook);
        expect(component.bookActionCompleted.emit).toHaveBeenCalledTimes(1);
      })
    });

  });
});

您可以訂閱您的bookActionCompleted EventEmitter 並在傳遞給 jest 函數的“ done ”函數參數的幫助下終止測試。

it('should emit action complete', (done) => {
    // test will be green if done cb is called:
    component.bookActionCompleted.subscribe(done);
    component.onBookActionClick(publishedBook);
})

我只是偶然偶然發現了答案。 將模擬更改為 return of(undefined) 而不是 of() 使發射方法觸發。

不知道為什么會這樣,很想知道是否有人有答案。

之前(不工作)

libraryService.publishBook.mockReturnValue(of());
libraryService.unpublishBook.mockReturnValue(of());

之后(工作)

libraryService.publishBook.mockReturnValue(of(defined));
libraryService.unpublishBook.mockReturnValue(of(defined));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM