用玩笑测试可观察物

ama*_*iny 5 observable rxjs jestjs

如何使用Jest测试Observable?

我有一个每秒触发〜的Observable,我想测试一下第一个事件是否在异常超时之前正确触发。

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

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

该测试通过了,但是如果我替换为toBe('anything'),它也通过了,所以我想我做错了。

我尝试使用expect.assertions(1),但它似乎仅适用于Promises。

CTS*_*_AE 8

Jest文档中有一些很好的示例,它们涉及传递测试参数。可以调用此参数来表示通过测试,也可以对其调用失败以使测试失败,或者可以超时并失败。

https://jestjs.io/docs/zh/asynchronous.html

https://alligator.io/testing/asynchronous-testing-jest/

例子

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

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

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

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

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

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

  // Fail after 1500ms
  setTimeout(() => { done.fail(); }, 1500);
}, timeToFail);
Run Code Online (Sandbox Code Playgroud)

  • Observables 和 async 是非常不同的概念。将 observable 视为异步适用于简单的用例(如这里突出显示的那个)。一旦事情变得复杂,您将很难让这些测试正常工作。这就是为什么 [`TestScheduler`](/sf/answers/4792941821/) 存在的原因 (2认同)

Lia*_*iam 8

测试任何 RXJS 可观察值(开玩笑或不开玩笑)的正确方法是使用TestSchedulerin rxjs/testing

例如:

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);
  });
});
Run Code Online (Sandbox Code Playgroud)

来自RXJS 大理石测试测试文档

如果您有一个简单的可观察量,尝试将可观察量等转换为承诺会很好。一旦事情变得更加复杂,如果不使用弹珠图和正确的测试库,您就会陷入困境。


Yoa*_*man 5

test('Test name', (done) => {
  service.getAsyncData().subscribe((asyncData)=>{
    expect(asyncData).toBeDefined();
       done();
    })
  });
})
Run Code Online (Sandbox Code Playgroud)


gin*_*alx 5

我在没有虚假计时器和超时的情况下测试 observable 的首选方法是 to asyncawait并使用resolvesrejects在预期的转换承诺上。

it('should do the job', async () => {
    await expect(myObservable
      .pipe(first())
      .toPromise())
      .resolves.toEqual(yourExpectation);
});

Run Code Online (Sandbox Code Playgroud)

更新:

在 Rxjs 7 及以后,您可以使用lastValueFromfirstValueFrom进行承诺转换

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

Run Code Online (Sandbox Code Playgroud)