在Jest中,如何对一个可观察到的方法进行单元测试

时间:2019-11-12 09:18:39

标签: typescript jestjs rxjs-observables

我的组件中有各种方法可以订阅注入的依赖项中的方法,这些方法返回可观察的结果。

我想编写Jest单元测试,以确保当这些可观察对象返回/错误时,我的方法会做正确的事情。

在下面的示例中,我试图编写一个测试来检查doAThing是否已触发。以下测试均无效。它们都失败,并显示

之类的错误
  

“ returnMyObservable.subscribe不是函数”。

// Example method to test component 
public testFunction (): void {
    this.myService.returnMyObservable.subscribe(
        ( value ) => this.doAThing( value )
    )
}
describe( 'myComponemt', () => {

    let fixture;
    let myServiceMock;

    beforeEach( () => {
        myServiceMock = {
            returnMyObservable: fn()
        }

        fixture = new myComponent( myServiceMock );
    });


    // 1) I have tried mocking with a returned value
    it ( 'should call do a thing when value is returned', () => {
        myServiceMock.returnMyOnservable.mockReturnValue( true );

        fixture.testFunction();

        expect( fixture.doAThing ).toHaveBeenCalled();
    });

    // 2) I have tried returning an observable
    it ( 'should call do a thing when value is returned', () => {
        myServiceMock.returnMyOnservable.mockReturnValue( of( true ) );

        fixture.testFunction();

        expect( fixture.doAThing ).toHaveBeenCalled();
    });

});

2 个答案:

答案 0 :(得分:1)

我还有其他一些错误,这些错误掩盖了我的测试实际存在的问题-我发现测试上述功能的最佳方法是:

describe( 'MyComponent', () => {
    let fixture;
    let myServiceMock;

    beforeEach( () => {
        myServiceMock = {
            returnMyObservable: jest.fn()
        }

        fixture = new MyComponent( myServiceMock );
    });

    it ( 'should call doAThing when value is returned', () => {
        const doAThingSpy = jest.spyOn( fixture, 'doAThing' );
        myServiceMock.returnMyOnservable.mockReturnValue( of( true ) );

        fixture.testFunction();

        expect( doAThingSpy ).toHaveBeenCalledWith( true );
    });
});

(这与在茉莉花中的使用方法几乎相同)

答案 1 :(得分:0)

这是解决方案:

index.ts

export class MyComponent {
  private myService;
  constructor(myService) {
    this.myService = myService;
  }
  public testFunction(): void {
    this.myService.returnMyObservable.subscribe(value => this.doAThing(value));
  }
  public doAThing(value) {}
}

index.spec.ts

import { MyComponent } from './';

describe('MyComponent', () => {
  let fixture;
  let myServiceMock;

  beforeEach(() => {
    myServiceMock = {
      returnMyObservable: {
        subscribe: jest.fn()
      }
    };
    fixture = new MyComponent(myServiceMock);
  });

  it('should call do a thing when value is returned', () => {
    let observer;
    myServiceMock.returnMyObservable.subscribe.mockImplementation(handler => {
      observer = handler;
    });
    jest.spyOn(fixture, 'doAThing');
    fixture.testFunction();
    observer();

    expect(fixture.doAThing).toHaveBeenCalled();
  });
});

覆盖率100%的单元测试结果:

 PASS  src/stackoverflow/58815471/index.spec.ts (7.367s)
  MyComponent
    ✓ should call do a thing when value is returned (5ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.ts |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        8.773s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58815471