2015-01-18 14 views
5

Mam projekt JavaScript, który chcę obserwować metodologię TDD. Wybrałem strukturę karmy i bibliotekę requirejs do tego i poszedłem za przykładem pokazanym w karmie docs here.jak zresetować moduł requirejs między testami jednostkowymi

Jest przykładem jednego pliku jednostka testu, który jest:

define(['app', 'jquery', 'underscore'], function(App, $, _) { 

    describe('just checking', function() { 

     it('works for app', function() { 
      var el = $('<div></div>'); 

      var app = new App(el); 
      app.render(); 

      expect(el.text()).toEqual('require.js up and running'); 
     }); 

     it('works for underscore', function() { 
      // just checking that _ works 
      expect(_.size([1,2,3])).toEqual(3); 
     }); 

    }); 

}); 

Głównym problemem tego podejścia jest to, że nie ma sposobu, aby wyczyścić moduł App dla każdego testu. Więc jeśli w aplikacji są jakieś zmiany (takie jak zmiany zmiennych zamykających itp.) W jednym wywołaniu it, mogą one wpływać na inne wywołanie it.

Czy ktoś może coś na ten temat zaproponować? Są to takie popularne narzędzia, nie mogę uwierzyć, że nikt nigdy nie wpadł na taką sytuację.

Tak więc, aby podsumować to pytanie, chciałbym prosić o odpowiedź na którekolwiek z tych bardziej szczegółowych nich:

  • jest jakiś sposób na „reset” (clear) moduł w requirejs? (faktycznie, przypuszczam, że nie ma takiego sposobu, z wyjątkiem ponownego ładowania wszystkich modułów po raz kolejny)
  • czy istnieje lepsze podejście do uruchamiania karmy i requirejs, aby moduły nie miały żadnych pozostałości (efektów ubocznych) innych testy (it wywołań funkcji) na nich?

Odpowiedz

3

Z pomocą Google znalazłem rozwiązanie tego problemu. Nie mogę powiedzieć, że jest idealny, ale działa co najmniej iw każdym teście wymagany moduł jest w stanie nieskazitelny.

pierwsze, jedno trzeba mieć swój plik main.js testowej tak, to jest prawie taka sama jak w docs, z wyjątkiem testów nie są zdefiniowane jako moduły i nie są uwzględniane jako zależności:

require.config({file 
    baseUrl: '/base', 
    paths: {}, 
    shim: {}, 
    deps: [], 
    callback: window.__karma__.start 
}); 

W głównym karma config musi być obecny ten (jeden konieczność dostosowania własnych ścieżek)

files: [ 
    {pattern: 'src/**/*.js', included: false}, 
    'tests/unit/**/*.js' 
], 

A w testach sami Wykorzystujemy jaśmin testy asynchroniczny możliwości i requirejs.undef Metoda "czyszczenia" modułu (który zresetuje wewnętrzny stan modułu ładującego, aby zapomnieć o poprzedniej definicji modułu, zgodnie z informacjami podanymi w docs).

Ta metoda ma jedną przyczynę, że nie zresetuje innych modułów, które są już załadowane i zależą od modułu resetowania, ale nie powinno to stanowić problemu, jeśli ktoś prawidłowo zapisuje swoje testy, to znaczy, że testuje tylko jeden moduł (i może być rodzajem rodzica, z którego dziecko dziedziczy pewne zachowanie), tak że nie powinno być trudno undef kilku modułów na jeden.

describe('Some/Module tests', function() { 
    'use strict' 
    var M 

    beforeEach(function(done) { 
     requirejs.undef('src/Some/GParentModule') 
     requirejs.undef('src/Some/ParentModule') 
     requirejs.undef('src/Some/Module') 
     require(['src/Some/Module'], function(m) { 
      M = m 
      done() 
     }) 
    }) 

    it('some description', function() { 
     var i = 0 

     for (var prop in M) { 
      i++ 
     } 
     expect(i).toEqual(1) 
     expect(prop).toEqual('init') 
     expect(M.init).toEqual(jasmine.any(Function)) 
    }) 
}) 

Sprawdziłem to, między it rozmowami zmian modułu nie utrzymują, więc przypuszczam, że to bezpieczne, aby korzystać z tej metody.

Dziękuję wszystkim za pomoc, jeśli ktoś ma lepszy sposób, odpowiedz tutaj.

1
  • jest jakiś sposób na "reset" (clear) moduł w requirejs?

Można użyć requirejs.undef(), ale dokumentacja wspomnieć kilka gotchas. I według mojej wiedzy nie ma połączenia, za pomocą którego można by powiedzieć "rozładuj ten moduł i wszystko, od czego zależy", co w złożonej aplikacji prawdopodobnie jest potrzebne.

  • jest jakieś lepsze podejście do uruchomienia karmę i requirejs tak, że moduły nie mają żadnych pozostałości (efekty uboczne) innych testów (IT) wywołuje funkcję na nich?

Lepszym rozwiązaniem jest zaprojektowanie aplikacji, tak że stan jest związany z obiektem ty instancję zamiast do modułu sama. To jest to, co robię w zestawie testów dla dużego zastosowania mojego. Hak beforeEach resetuje to, co wymaga zresetowania i od nowa tworzy aplikację dla każdego testu.

+0

dziękuję, ale nie mogę się zgodzić z twoją sugestią * zaprojektowania twojej aplikacji tak, aby stan był związany z obiektem, który tworzysz, a nie z samym modułem *, ponieważ nawet gdybym to zrobił (chociaż nie chcę tego robić) w ten sposób), problem utrzymuje się, przynajmniej w JavaScript. Z uwagi na fakt, że definicja modułu jest funkcją, nawet jeśli zainicjuję obiekt, nie mogę na nim polegać jako * jasne * dla każdego testu (niektóre zmienne zamknięcia mogą być co najmniej zmieniane). – user907860

+0

Wygląda na to, że znalazłem akceptowalne rozwiązanie, które zamierzam zamieścić jako odpowiedź poniżej – user907860

+0

@ user907860 Musisz mieć błędne przekonanie o tym, jak działa JavaScript, ponieważ ** jest całkiem wykonalne **. Jak już powiedziałem w mojej odpowiedzi, zrobiłem to. – Louis

Powiązane problemy