2013-02-01 40 views
6

Tôi có một vấn đề thử nghiệm mô hình mongoose tôiMongoose mô hình thử nghiệm đòi hỏi mô hình

Tôi có một cấu trúc như

  • ứng dụng
    • mô hình
      • Địa chỉ
      • tài
      • Tổ chức
    • kiểm tra

Cả hai mô hình người dùng và tổ chức cần phải biết mô hình Địa chỉ. Mô hình của tôi được cấu trúc như:

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

Trong ứng dụng bình thường, tôi yêu cầu Địa chỉ trước khi yêu cầu Người dùng và tổ chức và mọi thứ đều ổn. Bây giờ tôi đã viết các bài kiểm tra cho Người dùng và Tổ chức. Để có mô hình Địa chỉ được đăng ký, tôi gọi require('../models/Address.js') Điều này có tác dụng nếu tôi chạy một thử nghiệm. Nhưng nếu tôi chạy tất cả các bài kiểm tra trong một loạt tôi nhận được một lỗi vì tôi đã cố gắng để đăng ký Địa chỉ hai lần.

OverwriteModelError: Cannot overwrite Address model once compiled.

Làm cách nào để giải quyết vấn đề này?

+0

tôi đã trả lời một câu hỏi tương tự ở đây. http://stackoverflow.com/a/16248673/383217 –

Trả lời

12

Vấn đề là bạn không thể thiết lập mô hình mongoose hai lần. Cách dễ nhất để giải quyết vấn đề của bạn là tận dụng chức năng của node.js require.

Node.js lưu trữ tất cả cuộc gọi đến require để ngăn mô hình của bạn khởi chạy hai lần. Nhưng bạn gói các mô hình của bạn với các chức năng. Unwrapping họ sẽ giải quyết vấn đề của bạn:

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

giải pháp thay thế là để đảm bảo rằng mỗi mô hình khởi tạo một lần duy nhất. Ví dụ, bạn có thể khởi tạo tất cả các bạn module trước khi chạy thử nghiệm của bạn:

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

// run your tests using Address, User and Organization 

Hoặc bạn có thể thêm try catch tuyên bố mô hình của bạn để xử lý trường hợp đặc biệt này:

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

Cập nhật: Trong dự án của chúng tôi, chúng tôi có /models/index.js tệp để xử lý mọi thứ. Đầu tiên, nó gọi mongoose.connect để thiết lập kết nối. Sau đó, nó yêu cầu mọi mô hình trong thư mục models và tạo một từ điển của nó. Vì vậy, khi chúng tôi cần một số mô hình (ví dụ: user), chúng tôi yêu cầu nó bằng cách gọi require('/models').user.

+0

Tôi muốn đi với giải pháp đầu tiên nhưng tôi lo lắng vì các tham chiếu đến mongoose, tôi hy vọng điều này không phanh tham chiếu đến mongoose bởi vì tôi làm mongoose.connect trong tệp app.js của tôi, nhưng khi bạn nói nút sẽ thu thập các yêu cầu và cung cấp một bản sao nếu nó đã được yêu cầu? – pfried

+0

Refactored mã của tôi, loại bỏ các wrapper chức năng và hoạt động tốt, cảm ơn bạn! – pfried

+0

Có, nhưng trong trường hợp này bạn nên gọi 'mongoose.connect' trước khi khởi tạo bất kỳ mô hình nào của bạn. –

1

Câu hỏi này đã có một câu trả lời, nhưng đối với một cách duy nhất để thực hiện điều này kiểm tra https://github.com/fbeshears/register_models. Dự án mẫu này sử dụng tệp register_models.js bao gồm tất cả các mô hình từ một mảng tên tệp. Nó hoạt động thực sự tốt và bạn kết thúc với tất cả các mô hình của bạn khá nhiều bất cứ nơi nào bạn cần chúng. Hãy nhớ cache của node.js sẽ lưu các đối tượng trong dự án của bạn trong khi nó đang chạy.

0

Tôi sử dụng try/catch để giải quyết vấn đề này và nó hoạt động tốt. Nhưng tôi nghĩ đây không phải là cách tốt nhất để làm điều này.

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

giải pháp tốt nhất (IMO):

try { 
    mongoose.model('config') 
} catch (_) { 
    mongoose.model('config', schema) 
} 
Các vấn đề liên quan