Sử dụng bản vá giả để mô phỏng một phương thức cá thể


82

Tôi đang cố gắng mô phỏng thứ gì đó trong khi thử nghiệm ứng dụng Django bằng cách sử dụng thư viện thử nghiệm Mock được đặt tên theo trí tưởng tượng . Tôi dường như không thể làm cho nó hoạt động được, tôi đang cố gắng làm điều này:

models.py

from somelib import FooClass

class Promotion(models.Model):
    foo = models.ForeignKey(FooClass)
    def bar(self):
       print "Do something I don't want!"


test.py

class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'

    def test_enter_promotion(self):
        @patch.object(my_app.models.FooClass, 'bar')
        def fake_bar(self, mock_my_method):
            print "Do something I want!"
            return True

        self.client.get(reverse(view))

Tôi đang làm gì sai?


barthực tế là một "phương thức thể hiện" và tham số duy nhất của nó là self. Để trở thành một phương thức lớp, nó sẽ cần được tham số hóa bằng clsvà sẽ có thể được gọi là Promotion.foo().
cavaunpeu

Đối tượng có thể sửa chữa cần được trích dẫn như sau: @patch.object('my_app.models.FooClass', 'bar')
Lasma

2
@cavaunpeu - không (chỉ) tham số với cls, nhưng quan trọng hơn (vì selfclslàm bất cứ điều gì đặc biệt không có ý nghĩa trong python), được trang trí với@classmethod
dwanderson

Câu trả lời:


67

Để thêm vào câu trả lời của Kit, hãy chỉ định đối số thứ 3 để patch.object()cho phép chỉ định đối tượng / phương thức bị chế nhạo. Nếu không, một MagicMockđối tượng mặc định được sử dụng.

    def fake_bar(self):
        print "Do something I want!"
        return True

    @patch.object(my_app.models.FooClass, 'bar', fake_bar)
    def test_enter_promotion(self):
        self.client.get(reverse(view))
        # Do something I want!

Lưu ý rằng, nếu bạn chỉ định các đối tượng chế giễu, sau đó mặc định MagicMock()không còn thông qua vào đối tượng vá - ví dụ như không còn:

def test_enter_promotion(self, mock_method):

nhưng thay vì:

def test_enter_promotion(self):

http://www.voidspace.org.uk/python/mock/patch.html#patch-object


Tôi thích cách triển khai này hơn. Nó rõ ràng hơn, đặc biệt là đối với người mới bắt đầu trong Unit Testing.
Dorcioman

35

Ah Tôi đã bối rối về nơi để áp dụng trang trí vá lỗi đó. Đã sửa:

class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'

    @patch.object(my_app.models.FooClass, 'bar')
    def test_enter_promotion(self, mock_method):
        self.client.get(reverse(view))

20
Bạn tạo mối liên hệ giữa phương pháp giả mạo và phương pháp thực thi giả mạo ở đâu bây giờ?
physicalattraction

@physicalattraction, kết nối được thực hiện bởi đối số mock_methodđược truyền cho hàm kiểm tra. Tôi đã có thể sử dụng kỹ thuật này trong một trong những thử nghiệm của mình. Điều này hữu ích khi bạn chỉ muốn xác minh xem phương thức bị chế nhạo có được gọi hay không.
Kalyan Vedala

@ rcode74: Cách vá phương thức của một cá thể (một số đối tượng khác) bên trong phương pháp thử nghiệm. ví dụ: def my_method_to_be_tested (...): r = some_script.some_class (...); r.how_to_patch_this_method.
imsrgadich 10/09/18

1
@imsrgadich, bạn sẽ làm điều gì đó giống như r.how_to_patch_this_method = MagicMock (). Bạn có thể kiểm tra tài liệu MagicMock để biết cách gán hành vi cho đối tượng giả.
Kalyan Vedala
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.