2016-10-10 2 views
1

Учитывая кусок кода, как показано ниже, который принимается от reinforcejsКак проверить функцию в вар в JavaScript

var RL = {}; 
(function(global) { 
    var sampleWeighted = function(p) { 
     var r = Math.random(); 
     var c = 0.0;   // cumulative prob 
     for(var i=0, n=p.length; i<n; i++) { 
      c += p[i]; 
      if (c >= r) { return i; } 
     } 
     // assert(false) may happen if sum(p) < 1; 
     assert(false, 'wtf'); 
    }; 

// many content omitted 
... 
})(RL); 

export default RL; 

Как я могу получить доступ sampleWeighted и проверить его, пожалуйста? Я попытался ниже

import RL from './rl.js'; 

it('sampleWeighted',() => { 
    expect(RL.sampleWeighted([0.5, 0.5])).toEqual(1); 
}); 

Но он жалуется с ошибкой

FAIL src/lib/rl.test.js 
    ✕ sampleWeighted (1ms) 

    ● sampleWeighted 

    TypeError: _rl.RL.sampleWeighted is not a function 

     at Object.<anonymous> (src/lib/rl.test.js:7:46) 
     at process._tickCallback (internal/process/next_tick.js:103:7) 

Я новичок в тестировании JavaScript. В настоящее время я использую create-react-app для настройки рамки тестирования. Итак, какой способ проверить вышеприведенную функцию, пожалуйста? Если вы поняли, что делает sampleWeighted, пожалуйста, не стесняйтесь прокомментировать его.

+0

Вместо 'var sampleWeighted', попробуйте' global.sampleWeighted' – Rajesh

+0

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

+0

Вид. 'sampleWeighted' является частной функцией внутри' IIFE'. Код внутри него может использовать его, но не будет доступен для внешнего кода. – Rajesh

ответ

1

sampleWeighted в закрытии вашего IIFE (Immediate функции синтаксиса вызова)

таким образом, вы можете сохранить ваш метод частного как private public в Java, обратите внимание, у вас есть пройти глобальный, который RL, вы можете обращаться, что, как ваше пространство имен, и если вы хотите позвонить sampleWeighted, вам нужно приложить sampleWeighted к RL,

... 
RL.sampleWeighted = function() {} 
... 
+0

Его 'IIFE' (немедленное выполнение исполняемых функций) и его не закрытие, его область – Rajesh

+0

@Rajesh. Можете ли вы подтвердить, что оно написано в' var sampleWeighted', является неустойчивым? Кроме того, означает ли это, что мы не должны писать такой код вообще, если он нуждается в тестировании? – zyxue

+0

Что делать, если я хочу вызвать 'sampleWeighted' в другой части кода внутри' (function (global) {......} ', как его называть?' Global.sampleWeight' выглядит довольно многословным, да? – zyxue

1

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

Если вы используете систему сборки, вы можете сделать именно это.

var RL = {}; 
(function(global) { 
    var sampleWeighted = function(p) { 
     var r = Math.random(); 
     var c = 0.0;   // cumulative prob 
     for(var i=0, n=p.length; i<n; i++) { 
      c += p[i]; 
      if (c >= r) { return i; } 
     } 
     // assert(false) may happen if sum(p) < 1; 
     assert(false, 'wtf'); 
    }; 

    var api = { 
     bar: function() { 
      // public function `bar` returned from closure 
      return "bar" 
     } 
    }; 

    /* test-code */ 
     api._foo = foo 
    /* end-test-code */ 

    return api  

})(RL); 

export default RL; 

, а затем вы можете использовать "хрюкать-стрип-код"

npm install grunt-strip-code --save-dev 

Затем включите его в вашем Gruntfile:

grunt.loadNpmTasks('grunt-strip-code'); 


grunt.initConfig({ 
    strip_code: { 
    options: { 
     start_comment: "test-code", 
     end_comment: "end-test-code", 
    }, 
    your_target: { 
     // a list of files you want to strip code from 
     src: "dist/*.js" 
    } 
    } 
}) 


grunt.registerTask("test", [ 
    "concat", 
    "jshint", 
    "jasmine" 
]) 
grunt.registerTask("deploy", [ 
    "concat", 
    "strip-code", 
    "jshint", 
    "uglify" 
]) 

Rerefence - https://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/

+0

, который не работает, вы должны прикрепить свой api к глобальному объекту. вы не можете просто вернуть api. – Sean

+0

grunt-strip-code выглядит немного хакерским, это лучший способ сделать это? – zyxue

1

в вашем IIFE вы не приложили sampleWeighted к переданному в obj ect (глобальный). Поэтому убедитесь, что вы делаете что-то, как показано ниже в вашем IIFE:

global.sampleWeighted = sampleWeighted; 

Кроме того, в тестовом файле, вам необходимо получить доступ к этой функции с помощью:

RL.sampleWeighted 

Я надеюсь, что это помогает.

+0

Это работает. У меня сложилось впечатление, что этот способ IIFE поэтапно отказывается от модульной системы ES6 (например, [export] (https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export), правильно? – zyxue

+0

В некотором смысле, для некоторых применений ..., но IIFE также используется, если вы хотите выполнить функцию сразу после разбора скрипта, что я не уверен в том, для чего предназначены модули ES6. – Sean12

Смежные вопросы