Jest.js 用笑话检验观察值

0h4hbjxa  于 2023-01-18  发布在  Jest
关注(0)|答案(6)|浏览(232)

我如何用Jest测试观察值?
我有一个每秒触发~的可观测事件,我想在jest超时之前测试第一个事件是否被正确触发。

const myObservable = timer(0, 1000); // Example here

it('should fire', () => {
  const event = myObservable.subscribe(data => {
    expect(data).toBe(0);
  });
});

这个测试通过了,但是如果我用toBe('anything')替换,它也通过了,所以我猜我做错了什么。
我尝试使用expect.assertions(1),但它似乎只与承诺工作。

zpf6vheq

zpf6vheq1#

在Jest文档中有一些关于为测试传递参数的很好的例子,这个参数可以被调用来表示测试通过,或者你可以在它上面调用fail来使测试失败,或者它可以超时并失败。
https://jestjs.io/docs/en/asynchronous.html
https://alligator.io/testing/asynchronous-testing-jest/

示例

请注意,我将超时设置为1500毫秒

const myObservable = timer(0, 1000); // Example here

it('should fire', done => {
  myObservable.subscribe(data => {
    done();
  });
}, 1500); // Give 1500ms until it fails

使用 setTimeout查看是否失败的另一种方法

const myObservable = timer(0, 1000); // Example here

it('should fire', done => {
  myObservable.subscribe(data => {
    done();
  });

  // Fail after 1500ms
  setTimeout(() => { done.fail(); }, 1500);
}, timeToFail);
oknwwptz

oknwwptz2#

我更喜欢的测试可观察性的方法,没有假计时器和超时,是asyncawait和使用resolvesrejects对预期转换的承诺。

it('should do the job', async () => {
    await expect(myObservable
      .pipe(first())
      .toPromise())
      .resolves.toEqual(yourExpectation);
});
    • 更新日期:**

在Rxjs 7及更高版本中,您可以使用lastValueFromfirstValueFrom进行promise转换

it('should do the job', async () => {
    await expect(lastValueFrom(myObservable))
      .resolves.toEqual(yourExpectation);
});
7bsow1i6

7bsow1i63#

test('Test name', (done) => {
  service.getAsyncData().subscribe((asyncData)=>{
    expect(asyncData).toBeDefined();
       done();
    })
  });
})
w51jfk4q

w51jfk4q4#

测试任何可观察到的RXJS的正确方法(Jest或no)是使用rxjs/testing中的TestScheduler
例如:

import { TestScheduler } from 'rxjs/testing';
import { throttleTime } from 'rxjs/operators';
 
const testScheduler = new TestScheduler((actual, expected) => {
  // asserting the two objects are equal - required
  // for TestScheduler assertions to work via your test framework
  // e.g. using chai.
  expect(actual).deep.equal(expected);
});
 
// This test runs synchronously.
it('generates the stream correctly', () => {
  testScheduler.run((helpers) => {
    const { cold, time, expectObservable, expectSubscriptions } = helpers;
    const e1 = cold(' -a--b--c---|');
    const e1subs = '  ^----------!';
    const t = time('   ---|       '); // t = 3
    const expected = '-a-----c---|';
 
    expectObservable(e1.pipe(throttleTime(t))).toBe(expected);
    expectSubscriptions(e1.subscriptions).toBe(e1subs);
  });
});

RXJS marble testing testing docs
如果你有一个简单的可观察性,尝试将可观察性等转化为承诺效果很好。一旦事情变得更加复杂,如果不使用大理石图表和正确的测试库,你将会陷入困境。

v64noz0r

v64noz0r5#

上面提到了两种方法
1.取测试中的参数,在测试完成后调用它.
1.使用firstValueFrom(myObs)或lastValueFrom(myObs)将我们的可观察性转换为承诺,并对它们使用async wait ...
如果我们有多个观察对象需要测试,那么我们必须在测试中嵌套这些观察对象,因为我们只能调用done()一次。在这种情况下,异步等待方法会很方便。在这个例子中,当我们调用filter Customer时,所有三个观察对象都发出值,所以我们必须测试所有的观察对象。

it('Filter Customers based on Producers- Valid Case Promise way ',async()=>{
    
    service.filterCustomers('Producer-1');

    await expect(firstValueFrom(service.customers$)).resolves.toEqual(['Customer-1']);

    await firstValueFrom(service.customers$).then((customers:string[])=>{
      expect(customers).toEqual(['Customer-1']);
      expect(customers.length).toBe(1);
    })

    await expect(firstValueFrom(service.products$)).resolves.toEqual([]);
    await expect(firstValueFrom(service.types$)).resolves.toEqual([]);

  }).
8dtrkrch

8dtrkrch6#

这是使用fakeAsync的Angular 方法
假设我们有一个FooService,它有一个Observable closed$,每当我们调用服务的dismiss()方法时,它都会发出。

@Injectable()
export class FooService {
    private closeSubject$ = new Subject<void>();
    public close$ = this.closeSubject$.asObservable();
    
    public dismiss() {
        this.closeSubject$.next();
    }
}

然后我们可以像这样测试close$发射

describe('FooService', () => {
    let fooService: FooService;

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [FooService]
        });
        fooService= TestBed.inject(FooService);
    });

    it('should emit a close event upon calling dismiss()', fakeAsync(() => {
        const callbackSpy = jest.fn();
        fooService.close$.subscribe(() => {
            callbackSpy();
        });
        fooService.dismiss();
        tick();
        expect(callbackSpy).toHaveBeenCalledTimes(1);
    }));
});

相关问题