Python 对写入加密钱包文件的函数或方法进行单元测试的正确方法是什么?
我的代码看起来有点像这样:Python 对写入加密钱包文件的函数或方法进行单元测试的正确方法是什么?,python,unit-testing,wallet,Python,Unit Testing,Wallet,我的代码看起来有点像这样: def write_wallet_file_entry(name, value, wallet_file, wallet_password): some_code some_more_code_to_write_to_the_wallet ... 我正在使用Python(2.6)和unittest模块对这段代码进行单元测试。代码创建钱包文件(如果它不存在),然后向其中写入一组键值对 一旦我给钱包写了信,我就无法进行文本解析来确认写的内容是干净
def write_wallet_file_entry(name, value, wallet_file, wallet_password):
some_code
some_more_code_to_write_to_the_wallet
...
我正在使用Python(2.6)和unittest模块对这段代码进行单元测试。代码创建钱包文件(如果它不存在),然后向其中写入一组键值对
一旦我给钱包写了信,我就无法进行文本解析来确认写的内容是干净的
澄清:说明一个不太明显的问题:我不能使用“unittest.mock”或“mock”模块,这会使问题更容易解决。我的环境停留在python 2.6上,没有“virtualenv”,没有“mock”模块,不允许在系统上安装外部模块
任何建议都会非常有用。一些假设
这些假设不会改变我回答的要点,但它们将意味着我们可以清楚地了解术语,因为您还没有发布一篇文章
- “钱包文件”实际上是一个类似文件的对象。它遵循与文件流对象相同的语义,Python的
是该对象的直接包装器open()
- 只有
和wallet\u文件
是特定于wallet文件的wallet\u密码
和name
是要传递到文件中的键值对value
文件
对象,它已经经过了非常可靠的测试
单元测试的目的是测试您编写的代码,而不是测试外部服务。应该始终假定外部服务在单元测试中完成了它的工作-您只在集成测试中测试外部服务
您需要的是一种方法,以确保您发送要写入的值被正确接收且未被篡改,并且您创建文件的请求以您想要的格式接收。测试邮件,而不是收件人
方法
一种技术是将输入抽象为一个类,并将其子类化以使用伪方法。然后,您可以将该子类用作美化的mock,用于所有目的
换句话说,改变
def write_wallet_file_entry(name, value, wallet_file, wallet_password):
...
到
要进行测试,您现在可以创建MockWallet
:
class MockWallet(Wallet):
def __init__(self, wallet_file, wallet_password):
super(MockWallet, self).__init__(wallet, wallet_password)
self.didCheckExists = False
self.didAttemptWrite = False
self.didReceiveCorrectly = False
def exists(self):
super(MockWallet, self).exists()
self.didCheckExists = True
def write(self, name, value):
# ... some code to validate correct arguments were pass
self.didReceiveCorrectly = True
if super(MockWallet, self).write(name, value):
self.didAttemptWrite = True
现在,您可以在生产中使用相同的功能(只需通过Wallet
!)和测试(只需通过MockWallet
并检查该对象的属性!):
瞧!现在,您已经有了一个经过测试的写流,其中有一个简易的模拟,只使用了任意函数参数 您不需要外部库来编写自己的模拟对象。只需将
wallet_文件
和wallet_密码
抽象为wallet
类,将函数签名更改为接受wallet类,然后传入专门用于测试的子类。@AkshatMahajan-您能提供一个示例吗?此外,请将您的评论升级为回答,如果您提供示例,我将接受。当然。因为我对代码的工作原理一无所知,所以我假设name
,value
是要写入钱包文件的键值对。
class MockWallet(Wallet):
def __init__(self, wallet_file, wallet_password):
super(MockWallet, self).__init__(wallet, wallet_password)
self.didCheckExists = False
self.didAttemptWrite = False
self.didReceiveCorrectly = False
def exists(self):
super(MockWallet, self).exists()
self.didCheckExists = True
def write(self, name, value):
# ... some code to validate correct arguments were pass
self.didReceiveCorrectly = True
if super(MockWallet, self).write(name, value):
self.didAttemptWrite = True
import unittest
from ... import MockWallet, write_wallet_file_entry
class Test(unittest.TestCase):
def testWriteFlow(self):
mock = MockWallet()
name, value = 'random', 'more random'
write_wallet_file_entry(name, value, mock)
self.assertTrue(mock.didCheckExists)
self.assertTrue(mock.didAttemptWrite)
self.assertTrue(mock.didReceiveCorrectly)