2015-04-20 23 views
7

Tôi đang viết một lớp phối hợp hai công cụ (bộ điều khiển nguồn điều khiển từ xa và bộ điều khiển bus được sử dụng để điều khiển Thiết bị-Thử nghiệm) để thực hiện tất cả các loại phép đo trên Thiết bị Kiểm tra (DUT)).Thử nghiệm Đơn vị Python với hai đối tượng giả, cách xác minh lệnh gọi?

Truy cập vào cả hai công cụ được triển khai dưới dạng lớp Python và tham chiếu đến từng công cụ có sẵn cho lớp mới. Các DUT là hơi tinh tế và có một chuỗi sức mạnh rất cụ thể liên quan đến các cuộc gọi đến cung cấp điện và điều khiển xe buýt và phải xảy ra theo thứ tự cụ thể để tránh làm hỏng DUT.

Bây giờ tôi muốn viết một bài kiểm tra đơn vị cho lớp này. Tôi hiện đang sử dụng nosetests và mock-package cho việc này. Vì vậy, ý tưởng của tôi là giả lập cả hai lớp học cụ và xác minh thứ tự cuộc gọi chính xác cho những người đó.

Có vẻ như rất dễ dàng để xác minh thứ tự cuộc gọi cho từng lớp được mô phỏng. Do đó, tôi có thể tìm hiểu xem nguồn cung cấp điện đã được yêu cầu áp dụng chính xác điện áp pin đầu tiên chưa, sau đó điện áp miền kỹ thuật số và sau đó điện áp miền tương tự. Tôi cũng có thể thấy rằng các thanh ghi kỹ thuật số đã được lập trình cho các giá trị chính xác. Tuy nhiên, tôi đang mắc kẹt xác định nếu các cuộc gọi để viết các thanh ghi kỹ thuật số đã xảy ra giữa việc áp dụng điện áp miền kỹ thuật số và điện áp miền tương tự.

Vì vậy, câu hỏi của tôi là: Nếu tôi có hai đối tượng giả mạo, làm cách nào để xác minh thứ tự cuộc gọi cụ thể giữa các đối tượng đó? Mặc dù vậy, đầu tiên của tôi là kiểm tra dấu thời gian của các cuộc gọi nhưng dường như không tồn tại.

+0

Bạn có thể kiểm tra những điều sau đây đúng theo thứ tự: không phải A hay B được gọi; A được gọi nhưng B không phải; A và B được gọi? – jonrsharpe

+1

tôi nghĩ rằng bạn có thể sử dụng side_effect trên Mock để khởi động một chức năng khác sẽ báo cáo bất kỳ điều gì bạn muốn báo cáo - tức là lưu trữ thứ gì đó trong danh sách chung hoặc ở đâu đó thuận tiện – user3012759

+1

@ user3012759 Điều tương tự tôi đang nghĩ; bạn thậm chí có thể, ví dụ, sử dụng hiệu ứng phụ của A để khẳng định rằng B chưa được gọi. – chepner

Trả lời

8

Những gì bạn có thể làm là đặt mocks của mình vào đối tượng Mock() mới và kiểm tra các cuộc gọi của mô hình mới. Có lẽ một ví dụ đơn giản để hiểu:

>>> from unittest.mock import * 
>>> m0, m1 = Mock(), Mock() 
>>> m = Mock() 
>>> m.m0, m.m1 = m0, m1 
>>> m0() 
<Mock name='mock.m0()' id='140660445334224'> 
>>> m1() 
<Mock name='mock.m1()' id='140660445334608'> 
>>> m.mock_calls 
[call.m0(), call.m1()] 

Ok bây giờ chúng tôi đang ở vị trí tốt: chúng tôi chỉ có thể kiểm tra các cuộc gọi của m để xác minh theo đúng thứ tự:

>>> m.assert_has_calls([call.m0(), call.m1()]) 
>>> m.assert_has_calls([call.m1(), call.m0()]) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/dist-packages/mock.py", line 863, in assert_has_calls 
    'Actual: %r' % (calls, self.mock_calls) 
AssertionError: Calls not found. 
Expected: [call.m1(), call.m0()] 
Actual: [call.m0(), call.m1()] 

Như chúng ta muốn đèo đầu tiên và thứ tự nghịch đảo thất bại.

Khi bạn sử dụng patch chỉ cần lấy các mocks được trả lại bởi các bản vá lỗi và đặt chúng trong một mới Mock() làm vùng chứa. Làm kiểm tra của bạn trên các container ghi lại các lệnh gọi con.

+0

Aye, hoạt động hoàn hảo. Cảm ơn. Chỉ dành cho những người quan tâm, autospec cũng hoạt động trên các sub-mocks. – jan

+0

@jan Có, một khi bạn tạo ra giả lập của bạn đặt nó như là một đứa trẻ của một giả không thay đổi nó. –

+0

FYI, điều này không hiệu quả đối với tôi. Tôi tiếp tục nhận được một danh sách cuộc gọi trống. Tôi đã phải sử dụng 'attach_mock' để theo dõi đúng các cuộc gọi, xem câu trả lời này: https://stackoverflow.com/a/22677452/3405140 – moertel

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