2012-08-31 26 views
5

Tôi có một người quản lý khách hàng cho một mô hình Django mà override phương thức create cũng để tiết kiệm một số đối tượng có liên quan:Làm thế nào để bạn thử một phương pháp liên quan trong Django?

class CustomManager(models.Manager): 
    def create(self, amount, user, description): 
     txn = self.get_query_set().create(user, description) 
     txn.budget_transactions.create(amount) 
     return txn 

Câu hỏi của tôi là: làm thế nào để chế nhạo cuộc gọi đến txn.budget_transactions.create để nâng cao một ngoại lệ?

Thuộc tính budget_transactions của đối tượng txn là ví dụ của django.db.models.fields.related.RelatedManager. Sử dụng mock.patch để giả lập lớp này không hoạt động vì nó được khai báo động - nó không thể được nhập trực tiếp.

Có ai biết cách thực hiện việc này không?

+0

Bạn đang sử dụng thư viện Mock? Bạn có muốn sử dụng trình quản lý ngữ cảnh bản vá hoặc trình trang trí không? – santiagobasulto

+0

Tôi rất vui khi sử dụng thư viện giả nếu nó có thể giải quyết vấn đề này. Như tôi đã nói ở trên, việc sử dụng 'mock.patch' theo cách thông thường không hoạt động do khai báo động của lớp RelatedManager. – DavidWinterbottom

Trả lời

5

Lý do bạn không thể chỉ đặt Trình quản lý liên quan thành đối tượng giả là vì django đã ghi đè phương thức đặt trên đối tượng. Vì vậy, trong khi nó xuất hiện rằng các mô hình là nhận được thiết lập một cách chính xác vì không có khiếu nại, nó thực sự âm thầm thiết lập budget_transactions trở lại với các quản lý liên quan. Vì vậy, nếu bạn thực sự cần phải trả lại một mô hình thì bạn sẽ cần phải ghi đè lên phương thức lấy phương thức trả về Trình quản lý liên quan và trả về một đối tượng được giả lập thay thế.

nên kết thúc lookig somthing như:

@mock.patch('django.db.models.fields.related.ForeignRelatedObjectsDescriptor.__get__') 
def test_campaign_cancel(self, mock_manager): 
    mock_manager.return_value = mock.MagicMock() 
    mock_manager.return_value.create = Exception('Boom!') 

đó được cho biết có rất nhiều cạm bẫy để phương pháp này vì nó sẽ được trọng một phương pháp cốt lõi django và bây giờ ALL RelatedManagers sẽ trả về một đối tượng chế giễu. Từ những gì tôi đã có kinh nghiệm cho đến nay nó có thể dễ dàng hơn để khám phá các tùy chọn khác.

+0

Tôi đã phải giả lập 'django.db.models.fields.related.ReverseManyRelatedObjectsDescriptor .__ set__', nhưng cùng một cách tiếp cận chung. – AlanSE

Các vấn đề liên quan