2017-11-29 3 views
1

더 큰 React 앱의 일부인 JavaScript 함수를 테스트하려고합니다. 모듈 패턴을 많이 사용하는데, 정확하게 이해하지 못하는 것 같습니다. 여기에 내가 테스트하고있어 스크립트 (실제로 진짜 하나 그 GetFeedData.getFeedData 제외하고 실제 응용 프로그램에서 사용되는 것과 거의 동일한 외부 API에 대한 호출하게)입니다 :테스트에서 정의되지 않은 JavaScript mocked 함수가 반환되었습니다.

내가 할 시도하고있는 무슨
const GetFeedData = (function() { 
let feed, feedId; 
return { 
    getFeedId: function (sub) { 
     switch (sub) { 
      case '1': case '2': case '3': case '4': case '5': case '6': case 'S': 
       feedId = 1; 
       break; 
      case 'A': case 'C': case 'E': 
       feedId = 26; 
       break; 
      case 'N': case 'Q': case 'R': case 'W': 
       feedId = 16; 
       break; 
      case 'B': case 'D': case 'F': case 'M': 
       feedId = 21; 
       break; 
      case 'L': 
       feedId = 2; 
       break; 
      case 'G': 
       feedId = 31; 
       break; 
      } 
     }, 
     getFeedData: function() { 
      if (feedId === 2) { 
       feed = require('./MockData'); 
      } 
     }, 
     feed: feed 
    }; 
})(); 

const ReverseStop = (function() { 
    let stopIdN, stopIdS; 
    const stopData = require('../utils/stops'); 
    return { 
     reverseStop: function (sub, stop) { 
      var invalidEntries = 0; 
      function filterByName (item) { 
       if (item.stop_name == stop && typeof item.stop_id === 'string' && item.stop_id.charAt(0) == sub) { 
        return true; 
       } 
       invalidEntries ++; 
       return false; 
      } 
      var stopObjs = stopData.filter(filterByName); 
      for (var i = 0; i < stopObjs.length; i++) { 
       if (stopObjs[i].stop_id.charAt(stopObjs[i].stop_id.length - 1) == 'N') { 
        stopIdN = stopObjs[i].stop_id; 
       } else if (stopObjs[i].stop_id.charAt(stopObjs[i].stop_id.length - 1) == 'S') { 
        stopIdS = stopObjs[i].stop_id; 
       } 
      } 
     }, 
     stopIdN: stopIdN, 
     stopIdS: stopIdS 
    }; 
})(); 

export const IsDelayN = (function() { 
    let noDelay, yesDelay, nextArrival, delay; 
    return { 
     isDelay: function (sub, stop) { 
      GetFeedData.getFeedId(sub); 
      GetFeedData.getFeedData(); 
      ReverseStop.reverseStop(sub, stop); 
      var arrivals = []; 
      var delays = []; 
      function dataFilter() { 
       var invalidEntries = 0; 
       var feedObjs = GetFeedData.feed.filter(function (feedObj) { 
        if (feedObj.entity.trip_update.stop_time_update.stop_id == ReverseStop.stopIdN) { 
         return feedObj.entity.trip_update.stop_time_update; 
        } 
       }); 
       for (var i = 0; i < feedObjs.length; i++) { 
        arrivals.push(feedObjs.arrival.time.low); 
        delays.push(feedObjs.arrival.delay); 
       } 
      } 
      nextArrival = Math.min(...arrivals); 
      var delayIndex = arrivals.indexOf(nextArrival); 
      delay = delays.delayIndex; 
      if (delay === null || Math.ceil(delay/60) <= 5) { 
       noDelay = Math.ceil((nextArrival - GetFeedData.feed.header.timestamp.low)/60); 
      } else { 
       yesDelay = Math.ceil(delay/60); 
      } 
     }, 
     noDelay: noDelay, 
     yesDelay: yesDelay, 
     nextArrival: nextArrival 
    }; 
})(); 

export const IsDelayS = (function() { 
    let noDelay, yesDelay, nextArrival, delay; 
    return { 
     isDelay: function (sub, stop) { 
      GetFeedData.getFeedId(sub); 
      GetFeedData.getFeedData(); 
      ReverseStop.reverseStop(sub, stop); 
      var arrivals = []; 
      var delays = []; 
      function dataFilter() { 
       var invalidEntries = 0; 
       var feedObjs = GetFeedData.feed.filter(function (feedObj) { 
        if (feedObj.entity.trip_update.stop_time_update.stop_id == ReverseStop.stopIdS) { 
         return feedObj.entity.trip_update.stop_time_update; 
        } 
       }); 
       for (var i = 0; i < feedObjs; i++) { 
        arrivals.push(feedObjs.arrival.time.low); 
        delays.push(feedObjs.arrival.delay); 
       } 
      } 
      nextArrival = Math.min(...arrivals); 
      var delayIndex = arrivals.indexOf(nextArrival); 
      delay = delays.delayIndex; 
      if (delay === null || Math.ceil(delay/60) <= 5) { 
       noDelay = Math.ceil((nextArrival - GetFeedData.feed.header.timestamp.low)/60); 
      } else { 
       yesDelay = Math.ceil(delay/60); 
      } 
     }, 
     noDelay: noDelay, 
     yesDelay: yesDelay, 
     nextArrival: nextArrival 
    }; 
})(); 

내 함수에서 분리되어 있으므로 하나 또는 두 개의 매우 긴 함수가 아니라 내 보낸 함수에서 호출 할 수있는 몇 가지 짧은 함수가 있습니다. 몇 가지 변수 - GetFeedData.feed, ReverseStop.stopIdNReverseStop.stopIdS을 내 보낸 함수에서 호출해야하므로 콜백을 사용하는 것보다 모듈 패턴이 더 좋은 방법이라고 가정합니다. 나는 완전히 틀릴 수있다.

내 테스트에서는 콘솔에 로그 noDelay, nextArrivaldelay을 입력하여 정의되어 있는지 확인합니다. 그 정보가 도움이된다면 Jest를 사용하고 있습니다. 그들은 해당하지 않는 것 때문에 (즉 잘못된 경우에 저를 수정하시기 바랍니다) 지금 내 테스트의 다른 부분을 생략 하겠지만, 여기에 그 부분은 다음과 같습니다 내 console.log()들 모두

it('correctly takes input at beginning of api logic and outputs expected values at end',() => { 
    IsDelayN.isDelay('L', 'Lorimer St'); 
    IsDelayS.isDelay('L', 'Lorimer St'); 

    expect(IsDelayN.noDelay).toBeTruthy(); 
    expect(IsDelayN.yesDelay).toBeFalsy(); 
    expect(IsDelayS.noDelay).toBeTruthy(); 
    expect(IsDelayS.yesDelay).toBeFalsy(); 
    console.log('IsDelayN noDelay: ' + IsDelayN.noDelay); 
    console.log('IsDelayN nextArrival: ' + IsDelayN.nextArrival); 
    console.log('IsDelayN delay: ' + IsDelayN.delay); 
    console.log('IsDelayS noDelay: ' + IsDelayS.noDelay); 
    console.log('IsDelayS nextArrival: ' + IsDelayS.nextArrival); 
    console.log('IsDelayS delay: ' + IsDelayS.delay); 
}); 

테스트 이전에 통과하지만, console.log()은 모두 undefined입니다. 또한, 실제로 내 React 구성 요소에서 호출되는 스크립트가 동일한 결과를 내고 있습니다. 이 변수가 정의되어 있지 않으면 내 구성 요소를 null으로 렌더링하도록 설정했습니다. 그게 정확히 무슨 일이 일어나는지입니다.

이 내용을 이해하는 데 큰 도움이됩니다.

답변

0

모듈을 올바르게 설정하지 마십시오. 개체 값을 설정할 때 변수 값을 설정하기 만하면됩니다.

다음은 당신을 위해 작동합니다 :

var module = (function(){ 
 
     const ret = { 
 
     mutateSomething:function(value){ 
 
      //set otherValue on the object returned (mutate ret) 
 
      ret.otherValue = value; 
 
     } 
 
     ,otherValue:undefined 
 
     };//create the object first 
 
     return ret;//then return the object 
 
    }())//IIFE 
 

 
    console.log("before mutate:",module.otherValue); 
 
    module.mutateSomething("Hello World"); 
 
    console.log("after mutate:",module.otherValue);