我一直在研究使用unittest.mock将对象替换为假的对象(作为一个玩具项目,因为它看起来很有趣)。在documentation的一部分,有一个用io.StringIO
实例替换对象的例子,所以我可以看到理论上这应该是可行的,但是我不能让一个特定的玩具示例不需要跳转一些额外的环就可以工作。考虑此代码,保存为^ {CD2>}:
from unittest.mock import patch
class FileSystem:
def __init__(self, filename="file.txt"):
self.filename = filename
def write(self, content):
with open(self.filename, 'w') as f:
f.write(content)
def read(self):
with open(self.filename) as f:
return f.read()
class FileSystemFake:
def __init__(self, filename="file.txt"):
self.filename = filename
self.content = None
self.file_exists = False
def write(self, content):
self.content = content
self.file_exists = True
def read(self):
if self.file_exists:
return self.content
raise FileNotFoundError
class FileSystemFakeHoldingInstance(FileSystemFake):
instance = None
@classmethod
def __call__(cls, *args, **kwargs):
if cls.instance is not None:
return cls.instance
cls.instance = FileSystemFakeHoldingInstance(*args, **kwargs)
return cls.instance
def say_hello():
filesystem = FileSystem("hello.txt")
filesystem.write("hello")
def test_self_no_patch():
say_hello()
with open("hello.txt") as f:
assert f.read() == "hello"
@patch('main.FileSystem', new_callable=FileSystem)
def test_self(fake):
say_hello()
assert fake.read() == "hello"
@patch('main.FileSystem', new_callable=FileSystemFake)
def test_fake(fake):
say_hello()
assert fake.read() == "hello"
@patch('main.FileSystem', new_callable=FileSystemFakeHoldingInstance)
def test_fake_holder(fake):
say_hello()
assert fake.read() == "hello"
@patch('main.FileSystem', new_callable=FileSystemFakeHoldingInstance)
def test_fake_holder_reference(fake):
say_hello()
assert FileSystemFakeHoldingInstance.instance.read() == "hello"
玩具示例提供了一个类FileSystem
,该类将文件保存在文件系统上并将其读回。这个类是我为了避免文件系统访问而伪造的。我创建了一个FileSystemFake
类,它假装保存一个文件并将其读回;还有一个FileSystemFakeHoldingInstance
类,它保存了FileSystemFake
的一个实例,并实现了一个返回它的__call__
方法
我有一个简单的测试(test_self_no_patch
),它使用文件系统进行交互,工作正常。我的第一个困惑点发生在test_self
,它试图用对FileSystem
(同一类)的调用替换对FileSystem
的调用,但抛出“TypeError:'FileSystem'对象不可调用”。我在写了test_fake
之后写了这个,它用FileSystemFake
替换了FileSystem
失败,出现了一个类似的错误:“TypeError:'FileSystemFake'对象不可调用”
第二个问题在test_fake_holder
中可见,在这里我们得到一个FileNotFoundError
:根据文档,传递到函数中的对象是创建的伪对象。“write”函数可以正常运行,但对假函数调用“read”不会返回已写入的文本
最后,在test_fake_holder_reference
中,我从holder上的一个静态实例中读取了文本,这是有效的
为什么我会看到这种特殊的行为(类不可调用,补丁不返回“正确”的对象)?是否有一系列参数可以传递给patch
,使其直接与FileSystemFake
一起工作
目前没有回答
相关问题 更多 >
编程相关推荐