Использование оператора задержки RxJS в тестах Ava

Я являюсь автором программы на JavaScript, которую необходимо выполнить на основе ряда тестов. Я обнаружил, что каждый из этих тестов имеет одинаковый формат, и поэтому целесообразно генерировать тесты с использованием заводской функции.

Заводская функция называется testFactory и показана в приведенном ниже коде. Он вызывается с массивом данных, который после добавления логики моего приложения будет инструктировать фабрику о том, как построить конкретный тест. Функция фабрики также отвечает за выполнение тестов.

Я выбрал RxJS для достижения двухсекундной задержки, если строка "задержка" включена в данные, передаваемые на завод. (Моя предыдущая попытка реализации использовала обещания, но мне не удалось заставить этот подход работать.) Как вы можете видеть, это достигается с помощью оператора задержки Rx.

Ava была выбрана потому, что она имеет репутацию работы с RxJS. Как видите, я делаю звонки на Rx Subject из подписки на мою наблюдаемую.

В моем действительном коде приложения эта подписка делает вызовы конечному автомату, который реализует логику моего приложения, и данные из конечного автомата передаются в субъект через вызовы следующего метода субъекта в методе обратного вызова на конечном автомате. Вот почему я не могу просто подключить свою наблюдаемую непосредственно к методу тестирования Ava, а вместо этого должен пройти через предмет. Предмет был выбран вместо наблюдаемого для способности субъекта позволять делать вызовы его следующим и завершенным методам вне его определения.

Я удалил логику приложения из приведенного ниже кода, чтобы не путать проблему с этими деталями. Проблема возникает, когда строка 'delay' удаляется из массива данных. Когда этот код выполняется с данными, которые не содержат задержки, тест не проходит:

const data = [
  { r: 'c' },
  { l: 'c' },
  { l: 'n' },
  { l: 'c' }
];

Это терпит неудачу с: Test finished without running any assertions.

Как я могу получить это прохождение, когда нет "задержки" в массиве данных? Почему происходит сбой, когда в массиве данных нет "задержки"? Спасибо.

const ava = require('ava');
const { test } = ava;

const Rx = require('rxjs/Rx');
const { Observable, Subject } = Rx;

const data = [
  { r: 'c' },
  { l: 'c' },
  { l: 'n' },
  'delay',
  { l: 'c' }
];

const testFactory = (data) => {
  let subject = new Subject();

  // This code adds a delay property to each item which passes through, adding a
  // delay value based on a cumulative delay value maintained by the scan
  // operator. Items which are simply delays are marked with a 'skip' property
  // in the scan and skipped in the flatMap. Once the delay has been performed
  // by the delay operator, the added delay property is deleted. If there is a
  // simpler way in Rx to achieve this functionality, I'm open to suggestions
  // on refactoring this code. :-)
  const source = Observable.from(data)
    .scan((acc, val) => {
      if (val === 'delay') {
        return { skip: true, delay: acc.delay + 2000 };
      }
      return Object.assign(val, { delay: acc.delay });
    }, { delay: 0 })
    .flatMap((e) => {
      if (e.skip) {
        return Observable.empty();
      } else {
        return Observable.of(e)
          .delay(e.delay)
          .map(e => { delete e.delay; return e; });
      }
    });

  // This is the subscribe block which in my application called my state
  // machine. Since the state machine has been removed, the Subject is called
  // directly, instead of calling it from the callback tot the state machine.
  // Either way, the same problem exists. 
  source
    .subscribe({
      next: e => {
        subject.next(e);
      },
      complete: () => {
        subject.complete();
      }
    });

  // This test always passes. When the 'delay' is removed, the failure would
  // indicate to me that its never called.  
  test('', t => {
    // t.plan(1);
    return subject
      .map((n) => {
        t.true(true);
      });
  });
};

testFactory(data);

Примечание: Интересно, что когда импорт Ava удаляется вместе со строкой ниже, в которой импортируется тестовая функция Ava, а вызов тестовой функции заменяется обычной подпиской RxJS на тему, код работает как с задержкой, так и без нее. строка в структуре данных:

  // test('', t => {
  //   // t.plan(1);
  //   return subject
  //     .map((n) => {
  //       t.true(true);
  //     });
  // });

  subject.subscribe((v) => {
    console.log(JSON.stringify(v));
  });

Означает ли это, что проблема с моим использованием Ava?

1 ответ

Я не очень знаком с RxJS, наблюдаемыми или предметами, но есть ключ в Test finished without running any assertions.

Тесты AVA могут быть синхронными или асинхронными, когда вы возвращаете наблюдаемое, обещание или использование test.cb(t => t.end()), AVA также не проходит тесты, если до его завершения не было выполнено никаких утверждений.

В вашем случае, похоже, AVA определила, что ваш тест является синхронным. Вы должны убедиться, что он асинхронный, и заканчивать его только тогда, когда данные полностью используются.

Другие вопросы по тегам