Python单元测试和何时模拟

Python单元测试和何时模拟,python,unit-testing,mocking,Python,Unit Testing,Mocking,我正在一份新工作中开始一个新项目。这是我第一次大量使用Python。与我在静态类型语言中所遇到的困难相比,模仿是一种全新的怪兽。我亲自研究了团队的单元测试,并希望将其中一些测试从使用Dingus升级到Mock 今天早些时候,我遇到了一些检查转换类的测试。具体来说,它将十六进制数字字符串转换为Mongo ObjectId(唯一标识符)。我期望看到的是一个测试,它验证了给定一个有效的十六进制数,将返回一个具有相同十六进制数的ObjectId,或者,给定一个错误的十六进制数,将发生错误。相反,所有测试

我正在一份新工作中开始一个新项目。这是我第一次大量使用Python。与我在静态类型语言中所遇到的困难相比,模仿是一种全新的怪兽。我亲自研究了团队的单元测试,并希望将其中一些测试从使用Dingus升级到Mock

今天早些时候,我遇到了一些检查转换类的测试。具体来说,它将十六进制数字字符串转换为Mongo ObjectId(唯一标识符)。我期望看到的是一个测试,它验证了给定一个有效的十六进制数,将返回一个具有相同十六进制数的ObjectId,或者,给定一个错误的十六进制数,将发生错误。相反,所有测试都验证了ObjectId的创建和返回。事实上,ObjectId和十六进制数都被完全模拟掉了

现在,从字符串创建ObjectId不需要转到服务器或任何东西。一切都在本地运行

我向我的新同事询问了这个特殊的测试套件。他们的想法是,实际的转换应该使用集成测试进行验证,作为单元测试,单元测试应该做的就是确保代码按照预期从上到下流动,并创建和返回ObjectId。因此,基本上,测试只验证该类是否以预期的方式与环境交互

我已经编写单元测试很长时间了。根据我的经验,我根本不会使用mock,我只会验证转换是否按预期进行。这意味着从另一个模块与ObjectId类交互。也许我对单元测试的想法太笼统了。我一直保留连接到远程服务器、文件等的集成测试

在我看来,在本例中使用ObjectId与使用str或list没有什么不同。当然,我可以模拟str和list,但由于它们对于我的代码的工作是必不可少的,所以在我看来,模拟它们没有多大意义。我唯一关心与依赖项交互的时间是它可以更改测试结果的时间


编写简单检查代码流的单元测试有什么价值吗?单元测试不应该是验证代码的行为/正确性的结果吗?

因此,不看代码就很难准确地看到正在发生的事情,而仅仅基于您的解释

我同意你的看法。重要的是行为,而不是代码流

如果以后有人需要更改代码流以支持不同的情况(例如,使用具有不同参数的函数来实现相同的结果),该怎么办;他们可以在不破坏现有测试的情况下这样做

如果您升级正在使用的库,而现在调用该函数的结果实际上与您想要的结果不同,该怎么办?您的测试仍然有效(函数正在被调用),但单元测试实际尝试测试的内容却不起作用


实际上,如何使用模拟和测试仍然是一个相当年轻的学科。单元测试(以及单元测试中使用的各种策略,如模拟)是否被认为是“好事情”,目前还没有定论。但是,毫无疑问,我发现自己创建测试并不是为了测试行为,而是为了说我有测试,不恰当地使用mock是一种很好的方式,可以假装您已经创建了一个测试,而实际上您刚刚创建了一种错误的成就感,即您的代码现在已经过了更严格的测试。

虽然这是一个好问题,但我觉得这更多的是一个意见和讨论的问题,而不是一个可以正确回答的问题。我认为它更适合程序员网站stackexchange.com。