如何对实例化的模拟类对象断言

J选择

在我所测试的类的构造函数中,将实例化一个套接字对象并将其分配给一个类成员。我模拟了套接字类,并将模拟的套接字对象设置为套接字构造函数调用的返回值。然后,我想断言在该对象上调用了connect()和sendall()。当我在原始的模拟类对象或设置为在构造函数调用中返回的对象上断言时,总是收到断言错误,即未调用函数。

我知道我不能嘲笑正在测试的类(及其成员),因为那样会破坏这里的目的。

伪代码:

import socket

Class socketHandler():
    def __init__(...):
    self.mySocket = socket(...)
    ...
    self.mySocket.connect(...)

    def write(message):
        self.mySocket.sendall(message)

测试:

from unittest import mock
from unittest.mock import MagicMock #not sure if i need this
import pytest
import socketHandler

@mock.patch(socketHandler.socket)
def test_socket_handler(mockSocket):
    ...
    new_sock = mock_socket()
    mock_socket.return_value = new_sock

    mySocketHandler = SocketHandler(...)

    mock_socket.socket.assert_called_with(...)
    new_sock.connect.assert_called_with(...) #fails (never called)
    mock_socket.connect.assert_called_with(...) #fails (never called)
    #likewise for the sendall() method call when mysocketHandler.write(..)
    #is called

该测试的目的是:

  1. 确保使用正确的参数调用套接字库的构造函数。

  2. 确保使用正确的参数调用connect()。

  3. 当我将消息传递到mySocketHandler.write()方法中时,请确保完全按照我希望的方式调用sendall()。

J选择

完整答案来自@ ryanh119给出的提示以及此帖子链接

我将修复ryanh119给出的示例,并避免编辑我搞砸的原始问题,因此出于完整性考虑:

from unittest import mock
import pytest
import socketHandler

@mock.patch("app_directory.socketHandler.socket")
def test_socket_handler(mockSocketClass):

# mockSocketClass is already a mock, so we can call production right away.
mySocketHandler = SocketHandler(...)

# Constructor of mockSocketClass was called, since the class was imported
#like: import socket we need to:
mockSocketClass.socket.assert_called_with(...)

# Production called connect on the class instance variable
# which is a mock so we can check it directly.
# so lets just access the instance variable sock
mySocketHandler.mySocket.connect.assert_called_with(...)

# The same goes for the sendall call:
mySocketHandler.mySocket.sendall.assert_called_with(expectedMessage)

我还进行了一些研究,并且还有两个要提及的解决方案。它们不像上面的那样正确,但是在这里是:

  1. 通过更改__init__socketHandler来使用依赖注入,以使用一个套接字对象,并且仅在args中未提供时才实例化它。这样,我可以传递一个模拟或MagicMock对象,并用它来进行断言。
  2. 利用称为MonkeyPatch的功能非常强大的模拟/修补工具,该工具实际上可以修补/模拟类的实例变量。这种方法就像试图用火箭发射器杀死苍蝇一样。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章