2013-03-10 14 views
17

Obecnie piszę niektóre testy dla aplikacji nodejs. zakładać, że mam moduł tak:Jak testować jednostkę "prywatna" funkcja użyteczności w nodejs

module.exports = function myModule(moduleParam) { 
    var someVar; 
    .... 
    .... 
    function helper(param) { 
     return param + someVar; 
    } 
    return { 
     doSomething: function (bar) { 
      .... 
      .... 
      var foo = helper(bar); 
      .... 
      .... 
     } 
    }; 
}; 

Załóżmy, że funkcja „pomocnik” jest przydatny tylko w module i nie powinny być wystawione na zewnątrz.

Jaka jest "najlepsza praktyka" do testowania? (oczywiście, mogę przetestować funkcję DOSomething jako całość, ale w ten sposób funkcja "helpera" jest testowana w konkretnej sytuacji, w trybie "czarnej skrzynki").

Używam nodeunit jako ramy do testowania, dla tego mettera, ale mogę go zmienić w razie potrzeby.

+0

I don Myślę, że możesz go przetestować, ponieważ do tego potrzebujesz dostępu do zmiennych o zasięgu lokalnym. – Bergi

+0

Możesz pisać funkcja, która będzie dołączać tylko inną funkcję do eksportu, jeśli faktycznie przeprowadzasz testy? – phenomnomnominal

+0

@ Phenomnomnominal, masz na myśli coś jak funkcja eksportowana tylko wtedy, gdy zdefiniowana jest "globalna zmienna testowa" lub coś podobnego? – ArtoAle

Odpowiedz

22

Nie testujesz tego. Testowanie jednostkowe jest testem czarnej skrzynki. Oznacza to, że jedyną rzeczą, którą testujesz, jest publiczny interfejs, czyli umowa.

Funkcje prywatne takie jak te mogą się zdarzyć tylko po refaktoryzacji publicznych.

Więc jeśli konsekwentnie używasz TDD twoje prywatne funkcje są domyślnie testowane.

Jeśli to źle, najczęściej jest tak, ponieważ struktura jest zła. Następnie powinieneś pomyśleć o przeniesieniu swoich prywatnych rzeczy do dodatkowego modułu.

+1

To było to, o czym myślałem (i zrobiłem dla innych funkcji, które można ponownie wykorzystać). Nie zgadzam się, że te mogą pochodzić tylko z refaktoryzacji ... czy prywatna metoda java wychodzi tylko z refaktoryzacji publicznych? Nie sądzę ... w każdym razie, myślę, że strategia "przejścia do modułu" może być akceptowalna, mam tylko wątpliwości co do zakresu zamknięcia, który jest tracony na korzyść przechodzenia zależności, co nie jest pewne, czy zawsze jest dobra rzecz: – ArtoAle

+0

Jeśli postępujesz ściśle według TDD, nawet w Javie każda prywatna metoda będzie tylko wynikiem refaktoryzacji jednej (lub więcej) publicznych metod. Ale w każdym razie, myślę, że to jest droga :-) –

+0

Nie wiedziałem o tej ścisłej definicji :) w tym terminie, myślę, że odpowiedź jest uważana za poprawną. Czy możesz wskazać mi jakieś linki, gdzie znaleźć takie ok "oświadczenie" o TDD? Dzięki – ArtoAle

8

Ponieważ uważam, że testy są przydatnym narzędziem poza testowaniem jednostkowym, a TDD (this SO answer stanowi dobry argument), zrobiłem pakiet npm, aby pomóc w przypadkach takich jak twoje: require-from.

w was przykład to jak byś go używać:

Moduł-file.js:

function helper(param) { 
    return param + someVar; 
} 

module.exports = function myModule(moduleParam) { 
    var someVar; 
    .... 
    .... 
    return { 
     doSomething: function (bar) { 
      .... 
      .... 
      var foo = helper(bar); 
      .... 
      .... 
     } 
    }; 
}; 
module.helperExports = helper; 

importujące-file.js:

var requireFrom = require('require-from'); 
var helper = requireFrom('helperExports', './module-file')); 
var public = requireFrom('exports', './module-file')); // same as require('./module-file') 
+0

Mmm ...naprawdę nie jest to moje pytanie :) mam na myśli - zgadzam się, że twoje narzędzie jest użyteczne, ponieważ oddziela ono "publiczny" od "prywatnych" eksportów - ale moje pytanie dotyczyło raczej podejścia do tej sytuacji w TDD - rozumiem, że możesz łatać małpy wszystko, chciałem się dowiedzieć, czy istnieje dobra praktyka pisania kodu, i szczerze mówiąc, wyraźne eksportowanie czegoś wyłącznie w celu testowania jest czymś, czego naprawdę nie lubię, ponieważ uważam TDD za więcej wskazówek, jak napisz lepiej, więcej kodu wielokrotnego użytku :) – ArtoAle

+0

Dobre praktyki, takie jak wzorce, zależą od okoliczności. Deweloper wciąż musi brać pod uwagę kompromisy i osąd. Biorąc pod uwagę, że warto przetestować jednostki funkcjonalności w izolacji, aby utrzymać stabilny publiczny interfejs API i zminimalizować to, co jest naświetlone, biblioteka stanowi alternatywę dla wyodrębniania kodu do osobnego modułu. np .: Chcąc zachować powiązany kod lub uniknąć ryzyka, że ​​inne moduły zaczną zależeć od wyodrębnionego kodu (dzieje się to w większych zespołach). Więc nawet jeśli odpowiedź nie jest dla ciebie przydatna, może być w przyszłości lub dla innych osób. – DEADB17

+0

BTW: nie ma w tym przypadku łatania małp. Mechanizm jest taki sam, jak w przypadku zwykłego eksportu węzłów. – DEADB17