2017-09-11 2 views
0

저는 여러 가지 테스트에 대해 실행해야하는 JavaScript 프로그램의 작성자입니다. 나는이 테스트들 각각이 비슷한 포맷을 따르고 공장 기능을 사용하여 테스트를 생성하는 것이 적절하다는 것을 발견했다.Ava 테스트에서 RxJS 지연 연산자 사용

팩토리 함수는 testFactory라고하며 아래 코드에 표시됩니다. 일단 어플리케이션 로직이 추가되면 특정 테스트를 빌드하는 방법에 대해 공장에 지시 할 데이터 배열로 호출됩니다. 팩토리 함수는 테스트 실행을 담당합니다.

공장에 전달 된 데이터에 '지연'문자열이 포함되어 있으면 2 초 지연을 위해 RxJS를 선택했습니다. (이전의 구현 시도는 약속을 사용했지만,이 접근 방식을 작동시키지 못했습니다.) 알 수 있듯이, 이것은 Rx 지연 연산자를 사용하여 수행됩니다.

Ava는 RxJS와 협력하여 명성을 얻었 기 때문에 선정되었습니다. 보시다시피, 나는 내 관찰 가능 항목에 대한 구독으로 Rx Subject에 전화를 걸고 있습니다.

내 실제 응용 프로그램 코드에서이 구독은 내 응용 프로그램 논리를 구현하는 상태 시스템에 전화를 걸고 상태 시스템의 데이터는 해당 응용 프로그램의 콜백 메서드에서 주체의 다음 메서드 호출을 통해 주체에 공급됩니다. 상태 머신. 그렇기 때문에 관측 대상을 Ava 테스트 방법에 직접 꽂을 수는 없지만 대신 피사체를 관통해야합니다. 피험자가 그 정의 밖에서 다음 및 완전한 방법으로 호출 할 수 있도록하는 능력에 대해 관찰 가능한 것 대신 피험자가 선택되었습니다.

문제를 이러한 세부 정보와 혼동하지 않도록 아래 코드에서 내 응용 프로그램 논리를 제거했습니다. 문제는 '지연'문자열이 데이터 배열에서 제거 될 때 발생합니다. 이 코드는 지연을 포함하지 않는 데이터를 실행하면 테스트는 통과하지 않습니다에는 '지연'이 없을 때 나는이 통과를 얻는 방법 Test finished without running any assertions.

:

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

그것은 실패 데이터 배열에? 왜 데이터 배열에 '지연'이 없을 때 이것이 실패합니까? 고맙습니다.

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); 

참고 : 에바의 수입이 아바의 테스트 기능을 수입하는 아래의 라인 및 테스트 기능에 대한 호출과 함께 제거 될 때 흥미롭게도, 주제에 코드 작품을 구독하는 일반 RxJS로 대체 와 데이터 구조의 '지연'문자열없이 모두 :

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

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

이 문제가 아바의 내 사용 함께 표시합니까?

답변

0

나는 RxJS, 관찰 가능한 또는 주제에 정말 익숙하지 해요,하지만 당신은 관찰, 약속을 돌아가거나 test.cb(t => t.end())를 사용하는 동기가 될 수 Test finished without running any assertions.

AVA 테스트에서 단서 또는 비동기가있다. 테스트가 끝나기 전에 어설 션이 실행되지 않으면 AVA도 테스트에 실패합니다.

귀하의 경우에는 AVA가 귀하의 테스트가 동기라고 판단한 것으로 보입니다. 비동기인지 확인하고 데이터가 완전히 소모되었을 때만 종료해야합니다.