2013-02-01 10 views
6

mam problem testowania moich modeli Mongoosetestowanie modelu Mongoose wymagają modele

Mam strukturę jak

  • aplikacji
    • modele
      • Adres
      • użytkownika
      • Organization
    • Test

Oba modele użytkownika i Organizacja trzeba znać modelu adresu. Moje modele są skonstruowane tak:

module.exports = function (mongoose, config) { 

    var organizationSchema = new mongoose.Schema({ 

     name : { 
      type : String 
     }, 
     addresses : { 
      type : [mongoose.model('Address')] 
     } 

    }); 

    var Organization = mongoose.model('Organization', organizationSchema); 

    return Organization; 
}; 

W moim normalnym app i wymagają Adres przed wymagających użytkowników i Organizację i wszystko jest w porządku. Napisałem teraz testy dla użytkowników i organizacji. Aby mieć zarejestrowany model adresu, zadzwoń pod numer require('../models/Address.js'). To działa dobrze, jeśli wykonuję jeden test. Ale jeśli uruchomię wszystkie testy w partii, otrzymam błąd, ponieważ próbuję zarejestrować adres dwa razy.

OverwriteModelError: Cannot overwrite Address model once compiled.

Jak mogę rozwiązać ten problem?

+0

Odpowiedziałem tutaj podobne pytanie. http://stackoverflow.com/a/16248673/383217 –

Odpowiedz

12

Problem polega na tym, że nie można dwukrotnie ustawić modelu mangusty. Najłatwiejszym sposobem rozwiązania problemu jest skorzystanie z funkcji node.js require.

Node.js buforuje wszystkie wywołania do require, aby zapobiec dwukrotnemu zainicjowaniu modelu. Ale owijacie swoje modele funkcjami. Rozpakowanie ich rozwiąże Twój problem:

var mongoose = require('mongoose'); 
var config = require('./config'); 

var organizationSchema = new mongoose.Schema({ 
    name : { 
     type : String 
    }, 
    addresses : { 
     type : [mongoose.model('Address')] 
    } 
}); 

module.exports = mongoose.model('Organization', organizationSchema); 

Alternatywnym rozwiązaniem jest upewnienie się, że każdy model został zainicjowany tylko raz. Na przykład, można zainicjować was wszystkich modułów przed uruchomieniem swoich badań:

Address = require('../models/Address.js'); 
User = require('../models/User.js'); 
Organization = require('../models/Organization.js'); 

// run your tests using Address, User and Organization 

Albo można dodać try catch oświadczenie modeli obsłużyć ten szczególny przypadek:

module.exports = function (mongoose, config) { 

    var organizationSchema = new mongoose.Schema({ 

     name : { 
      type : String 
     }, 
     addresses : { 
      type : [mongoose.model('Address')] 
     } 

    }); 

    try { 
     mongoose.model('Organization', organizationSchema); 
    } catch (error) {} 

    return mongoose.model('Organization'); 
}; 

Aktualizacja: W naszym projekcie mamy plik /models/index.js, który zajmuje się wszystkim. Najpierw wywołuje mongoose.connect, aby nawiązać połączenie. Następnie wymaga każdego modelu w katalogu models i tworzy jego słownik. Tak więc, gdy potrzebujemy jakiegoś modelu (np. user), wymagamy tego, dzwoniąc pod numer require('/models').user.

+0

Chciałbym pójść z pierwszym rozwiązaniem, ale martwię się z powodu odniesień do mangusty, mam nadzieję, że to nie zahamuje odniesienia do mangusty, ponieważ robię mongoose.connect w moim pliku app.js, ale jak powiedziałeś, węzeł zbierze wymagania i da kopię, jeśli jest już wymagana? – pfried

+0

Refaktoryzowałem mój kod, usunąłem funkcję i działa dobrze, dziękuję! – pfried

+0

Tak, ale w takim przypadku powinieneś zadzwonić do 'mongoose.connect' przed zainicjowaniem dowolnego ze swoich modeli. –

1

już to pytanie odpowiedzi, ale na wyjątkowy sposób do osiągnięcia tego sprawdzić https://github.com/fbeshears/register_models. Ten przykładowy projekt korzysta z pliku register_models.js, który zawiera wszystkie modele z tablicy nazw plików. Działa bardzo dobrze i kończysz ze wszystkimi modelami praktycznie wszędzie tam, gdzie ich potrzebujesz. Należy pamiętać, że pamięć podręczna node.js będzie buforować obiekty w projekcie podczas jego działania.

0

Używam try/catch, aby rozwiązać ten problem i działa dobrze. Ale myślę, że nie jest to najlepszy sposób na zrobienie tego.

try{ 
    var blog = mongoose.model('blog', Article); 
} catch (error) {} 
2

Najlepsze rozwiązanie (IMO):

try { 
    mongoose.model('config') 
} catch (_) { 
    mongoose.model('config', schema) 
} 
Powiązane problemy