如何测试具有严重副作用的代码?

时间:2013-06-21 04:35:19

标签: unit-testing testing

单元测试在开发过程中非常重要。但是,测试一些代码并不容易。

如果我有这样的代码:

class Filesystem():

    def destroy(self, fs):
        os.system("mkfs.ext4 %s" % fs)
        #assert(self.size(fs) == 0)

我无法破坏测试的文件系统。

对于这种情况,我可以在UNIX上创建一个基于文件的驱动器进行测试。

但是,如果是API类:

class Blog():

    def post(self, text):
        blog.library.post(self.access_key, text)

我不想发布博客文章进行测试。

我该怎么办?

4 个答案:

答案 0 :(得分:4)

对于单元测试:

您的类不应直接与blog.library进行交互,而应通过您注入Blog类依赖关系的某个中间层进行交互。对于测试,您可以为它创建一个模拟,并声明使用预期参数调用了预期的方法。

对于功能/集成测试:

您设置了一个虚拟博客引擎并执行真正的帖子。然后检查该帖子是否真的出现在http请求的页面上。

答案 1 :(得分:3)

不是专家,但我相信嘲笑就是答案。

你不想发表一篇文章,事实上你的测试代码根本不需要一篇 REAL 文章,你只需要伪造一个对象(我们称之为:mocking)并让它表现就像一篇真正的文章,这样你的真实代码就可以完成它的工作,这就足够了。

请记住,测试的目的是确保您的代码正常运行。在OO编程中,我们将所有内容视为对象,因此当您发布文章时,它实际上会创建一个对象,该对象代表现实世界中的真实文章。模拟假对象足以表达代码的行为,因此您根本不必撰写真正的文章,只是为了证明您的代码会创建一个很可能是帖子足够的对象。

答案 2 :(得分:1)

正如其他人所说,嘲笑会在这里得到你的帮助。有许多可用的模拟框架 - 我更喜欢Mockito,因为它看起来最直观(对我而言)

我发现this article非常快速且清晰地涵盖了基础知识

Mockito不能模拟静态方法,但可以与PowerMock一起使用来实现这一点。关于如何做到这一点,网络上存在大量的例子(特别是SO)。话虽如此,我总觉得不得不依靠PowerMock一般在我的代码中指出一些臭味。

修改

刚才意识到我是从Java角度谈论,而这似乎不是你目前的环境

结束编辑

答案 3 :(得分:1)

像阿尔伯特所说,它应该是mock up entity

在.NET中,我创建了您要测试virtual的这些方法,以便我可以在Blog MockedBlog中扩展真实实体,现在MockedBlogoverride有一个Post()方法public class MockedBlog : Blog { public void override Post(string text) { PostMethodWasCalled = true; } public bool PostMethodWasCalled {get;set;} } ,我检查Mm测试是否达到了这样的方法:

var mockup = new MockedBlog();
// do the preparation, then post
mockup.Post("hello world");
Assert.IsTrue(mockup.PostMethodWasCalled);

在测试中,我会做这样的事情

{{1}}