2013-02-01 79 views
6

我有一個問題測試我的貓鼬模型貓鼬模型試驗要求的模型

我有一個像

  • 應用程序的結構
    • 車型
      • 地址
      • 用戶
      • 組織
    • 測試

這兩款機型的用戶和組織需要知道模型地址。我的模型結構類似:

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; 
}; 

在我的正常程序,我需要用戶和組織之前需要地址,一切都很好。我現在爲用戶和組織編寫測試。爲了讓地址模式註冊我呼籲require('../models/Address.js')這工作正常,如果我運行一個測試。但是,如果我在一批中運行所有測試,我會得到一個錯誤,因爲我試圖註冊地址兩次。

OverwriteModelError: Cannot overwrite Address model once compiled.

我如何解決這個問題?

+0

我在這裏回答了類似的問題。 http://stackoverflow.com/a/16248673/383217 –

回答

12

問題是你不能設置貓鼬模型兩次。解決您的問題的最簡單方法是利用node.js require函數。

Node.js將所有調用緩存到require,以防止模型初始化兩次。但是你用功能包裝你的模型。展開他們將解決你的問題:

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); 

替代解決方案是確保每個模型對其進行初始化一次。例如,您可以運行測試之前初始化所有你模塊:

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

// run your tests using Address, User and Organization 

也可以添加try catch聲明,你的模型來處理這種特殊情況:

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'); 
}; 

更新:在我們的項目中,我們有/models/index.js文件來處理一切。首先,它調用mongoose.connect建立連接。然後它需要models目錄中的每個模型並創建它的字典。所以,當我們需要一些模型(例如user)時,我們需要通過調用require('/models').user

+0

我想一起去的第一個解決方案,但我很擔心因爲引用貓鼬,我希望這並不制動參考貓鼬因爲我做mongoose.connect在我的app.js文件中,但正如你所說節點將收集需求並給出一個副本,如果它已經是必需的? – pfried

+0

重構了我的代碼,刪除了函數包裝器並正常工作,謝謝! – pfried

+0

是的,但在這種情況下,您應該在初始化任何模型之前調用'mongoose.connect'。 –

1

已經這個問題的線程都有一個答案,而是一種獨特的方式來完成這項檢查https://github.com/fbeshears/register_models。此示例項目使用了一個register_models.js,其中包含文件名數組中的所有模型。它運作得非常好,你可以隨時隨地找到你需要的所有模型。請記住,node.js的緩存會在項目運行時緩存項目中的對象。

0

我使用try/catch解決這個問題,它工作正常。但我認爲這不是做這件事的最好方法。

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

最佳解決方案(IMO):

try { 
    mongoose.model('config') 
} catch (_) { 
    mongoose.model('config', schema) 
}