Ngoại lệ trả về mô hình giả lập không đáng tin cậy nhất trong python

Joshua J. Kugler

2020-08-21 22. 27. 40 UTC

liên kết cố định

Xin chào. Tôi đang sử dụng Mock để đưa ra một ngoại lệ trong một chức năng dưới dạng tác dụng phụ.
Tuy nhiên, Mock đang định nghĩa lại hoàn toàn chính ngoại lệ đó, biến nó thành một
đối tượng MagicickMock, tạo ra ngoại lệ Python

TypeError. bắt các lớp không kế thừa từ BaseException không
được phép

Đây là trường hợp thử nghiệm tối thiểu có thể lặp lại của tôi.

# test_case. p
#. /usr/bin/python3

từ unittest. bản vá nhập mô phỏng

gói nhập. mô-đun

print('Trước khi trình vá bắt đầu. ', bưu kiện. mô-đun. MyException)

patcher = patch('gói. module')
mock_hvac = patcher. start()

print('Sau khi patcher bắt đầu. ', bưu kiện. mô-đun. MyException)

thử.
print('Ngay trước khi tăng. ', bưu kiện. mô-đun. MyException)
nâng gói. mô-đun. MyException

ngoại trừ gói. mô-đun. ngoại lệ của tôi.
print('Có ngoại lệ')

package/__init__. py
# Empty

gói/mô-đun. py
class MyException(BaseException).
vượt qua

Đầu ra.
$ python3. 6 --version
Python 3. 6. 9
$ python3. 6 trường hợp thử nghiệm. py
Trước khi bắt đầu trình vá lỗi.
Sau khi patcher bắt đầu.
id='140188666285696'>
Ngay trước khi tăng.
Traceback (lần gọi gần đây nhất).
Tệp "test_case. py", dòng 21, trong
gói nâng cao. mô-đun. MyException
TypeError. ngoại lệ phải xuất phát từ BaseException

Trong quá trình xử lý ngoại lệ trên, một ngoại lệ khác đã xảy ra.

Truy nguyên (lần gọi gần đây nhất).
Tệp "test_case. py", dòng 23, trong
ngoại trừ gói. mô-đun. ngoại lệ của tôi.
TypeError. bắt các lớp không kế thừa từ BaseException không
được phép

Điều này cũng gây ra sự cố cho các tác dụng phụ của Mô phỏng. Trong dòng mã này trong
mock. py (dòng 997 cho tôi).

nếu hiệu ứng không phải là Không có.
if _is_Exception(hiệu ứng).
tăng hiệu ứng

Hàm _is_Exception() kiểm tra ngoại lệ thông qua.

return (
isinstance(obj, BaseExceptions) hoặc
isinstance(obj, type) và issubclass(obj, BaseExceptions)< .
)

Which of course is false, because it's been replaced by a MagicMock object, so
exception side effects aren't properly raised.

Theo https. // tài liệu. con trăn. tổ chức/3. 6/thư viện/đơn vị. chế nhạo. html#calling
gọi hàm sau khi đặt side_effect sẽ làm tăng Ngoại lệ,
không phải đối tượng MagicMock.

https. // tài liệu. con trăn. tổ chức/3. 6/thư viện/đơn vị. chế nhạo. html#unittest. chế nhạo. Mock cũng
nói "Mặt khác, side_effect có thể là một lớp hoặc trường hợp ngoại lệ. Trong
trường hợp này, ngoại lệ sẽ được đưa ra khi mô phỏng được gọi. "

Vì vậy, điều này dường như không hoạt động như thiết kế, hoặc ít nhất là không như tài liệu.
Điều này đang tạo ra một số vấn đề thực sự nghiêm trọng đối với việc kiểm tra mã của chúng tôi, vì chúng tôi muốn
một chức năng có tác dụng phụ của một Ngoại lệ và bắt ngoại lệ đó, nhưng .
we can do neither when it has been replaced by a MagicMock object.

Cảm ơn vì bất kỳ mẹo, gợi ý nào hoặc "Bạn đang làm sai. " giáo dục. . )

j

--
Joshua J. Kugler - Fairbanks, Alaska - ***@azariah. com
Azariah Enterprises - Lập trình và thiết kế trang web
Khóa PGP. http. //pgp. mit. edu/ ID 0x68108cbb73b13b6a

Kushal Kumaran

2020-08-22 03. 52. 38 UTC

liên kết cố định

Bạn có thể thử một cái gì đó giống như những gì được đề cập trong
https. // tài liệu. con trăn. org/3/library/unittest. ví dụ giả. html#partial-mocking

Xem bên dưới.

Bài đăng của Joshua J. Kugler
Xin chào. Tôi đang sử dụng Mock để đưa ra một ngoại lệ trong một chức năng dưới dạng tác dụng phụ.
Tuy nhiên, Mock đang định nghĩa lại hoàn toàn chính ngoại lệ, biến nó thành
đối tượng MagicickMock, tạo ra ngoại lệ Python
TypeError. bắt các lớp không kế thừa từ BaseException không
được phép
Đây là trường hợp thử nghiệm tối thiểu có thể lặp lại của tôi.
# test_case. p
#. /usr/bin/python3
từ unittest. bản vá nhập mô phỏng
gói nhập. mô-đun
print('Trước khi trình vá bắt đầu. ', bưu kiện. mô-đun. MyException)

orig_Exception = gói. mô-đun. MyException

Bài đăng của Joshua J. Kugler
patcher = patch('gói. module')
mock_hvac = patcher. start()
print('Sau khi patcher bắt đầu. ', bưu kiện. mô-đun. MyException)

gói. mô-đun. MyException = orig_Exception
print('Sau khi khôi phục ngoại lệ. ', bưu kiện. mô-đun. MyException)

Bài đăng của Joshua J. Kugler
print('Ngay trước khi tăng. ', bưu kiện. mô-đun. MyException)
nâng gói. mô-đun. MyException
print('Có ngoại lệ')
package/__init__. py
# Empty
gói/mô-đun. py
pass
$ python3. 6 --version
Python 3. 6. 9
$ python3. 6 trường hợp thử nghiệm. py
Trước khi bắt đầu trình vá lỗi.
Sau khi patcher bắt đầu.
id='140188666285696'>
Ngay trước khi tăng.
Tệp "test_case. py", dòng 21, trong
gói nâng cao. mô-đun. MyException
TypeError. ngoại lệ phải xuất phát từ BaseException
Tệp "test_case. py", dòng 23, trong
TypeError. việc bắt các lớp không kế thừa từ BaseException không
được phép
Điều này cũng gây ra sự cố cho các tác dụng phụ của Mô phỏng. Trong dòng mã này trong
tăng hiệu ứng
return (
isinstance(obj, BaseExceptions) hoặc
isinstance(obj, type) and issubclass(obj, BaseExceptions)
)
Which of course is false, because it's been replaced by a MagicMock object, so
exception side effects aren't properly raised.
Theo https. // tài liệu. con trăn. tổ chức/3. 6/thư viện/đơn vị. chế nhạo. html#calling
gọi hàm sau khi đặt side_effect sẽ làm tăng Ngoại lệ,
không phải đối tượng MagicMock.

Nó sẽ tăng những gì bạn yêu cầu nó tăng. Bạn phải duy trì
tham chiếu đến đối tượng Ngoại lệ ban đầu, để bạn có thể tiếp tục sử dụng
đối tượng đó sau khi chế nhạo.

Bài đăng của Joshua J. Kugler
https. // tài liệu. con trăn. tổ chức/3. 6/thư viện/đơn vị. chế nhạo. html#unittest. chế nhạo. Mock cũng
nói "Mặt khác, side_effect có thể là một lớp hoặc trường hợp ngoại lệ. Trong
trường hợp này, ngoại lệ sẽ được đưa ra khi mô phỏng được gọi. "
Vì vậy, điều này dường như không hoạt động như thiết kế, hoặc ít nhất là không như tài liệu.
Điều này đang tạo ra một số vấn đề thực sự nghiêm trọng đối với việc kiểm tra mã của chúng tôi, vì chúng tôi muốn
một chức năng có tác dụng phụ của một Ngoại lệ và bắt ngoại lệ đó, nhưng .
we can do neither when it has been replaced by a MagicMock object.
Cảm ơn vì bất kỳ mẹo, gợi ý nào hoặc "Bạn đang làm sai. " giáo dục. . )

Vấn đề của bạn hoàn toàn được mô tả bởi thực tế là bạn chỉ ra. gói
. mô-đun. Tên MyException đã được trỏ đến một đối tượng MagicMock.

Nếu bạn không muốn điều đó, bạn phải khôi phục lại tên bạn muốn.

--
trân trọng,
kushal