在哪里/什么测试?模拟,存根,功能,单元......(在Ruby / Rails中)?

时间:2010-07-30 00:35:07

标签: ruby-on-rails unit-testing testing functional-testing stubbing

我正在尝试测试一个相当大的Rails应用程序,我可能应该一直这样做但从未感到完全舒服。现在我正在进行功能测试,看看是否成功创建了用户。基本上,我想测试一些事情:

  • 用户是否已保存(即,如果数据库中有新记录)
  • 他的信息(姓名,电子邮件等)是否正确
  • 是否已将几个字段自动添加到数据库before_create
  • 是否发送了电子邮件
  • 电子邮件文本是否合适(即,替换电子邮件模板中的用户名和激活链接)

据我了解,单元测试旨在测试模型,功能测试应该测试控制器。我上面提到的几个测试应该是单元测试,正如我所看到的那样 - 具体来说,我认为我可以确保输入正确映射到数据库字段,并且before_create过滤器在使用User模型的单元测试中工作。 / p>

其他人似乎要求进行功能测试 - 是否发送了电子邮件(可能是其文本 - 尽管可能属于UserEmail测试?)以及是否有新记录。

这是关于嘲笑/剔除的问题。在用户控制器功能测试中,我应该确保使用适当的参数调用user.save,还是应该测试数据库是否获得新记录?前者似乎需要一个存根并假设,由于Rails经过如此好的测试,如果在用户模型上调用.save,则对象将被成功保存。但后者(例如,调用assert_difference)感觉更彻底。选择哪个?

很抱歉,如果这涉及到一个问题 - 我理解这是一个很大的话题,但我希望理解这样一个特定的(如果长的)例子可以澄清一般的测试。

谢谢!

2 个答案:

答案 0 :(得分:1)

这不是一个容易回答的问题。基本上是there are two camps在Rails世界中。一个阵营会告诉你使用模拟,因为它会使你的测试更快。另一个阵营将告诉你使用数据库进行测试,因为它会更“忠实”,因为它测试数据库表具有正确的列,而mock不会这样做。两个阵营都会告诉你他们的测试风格更清晰: - )

我的建议是尝试一种方式,然后尝试另一种方式。看看什么对你有用。最重要的是尽量确保你的测试清晰而富有表现力。您可以找到有关如何开始测试Rails in this presentation by Gregg Pollack的提示。

答案 1 :(得分:1)

我喜欢做功能测试的方法是不要模拟/存根。基本上,一般来说,存根/模拟对于单元测试非常有用,因为它允许您隔离类或功能单元。现在,当涉及到集成和功能测试时,目的是测试“实际”类的交互,因此您需要避免模拟/存根。

因此,在您的情况下,我会在为用户控制器进行功能级别测试时涉及数据库。如果您决定存根持久层,我会认为您是对控制器进行单元测试(假设没有其他依赖项) - 这样的测试不允许您捕获持久层的问题(例如,数据库中的不兼容更改)架构,数据库连接问题等。)。

底线是这两种做法都是有效的,但这种做法的适当方式取决于你的目标是什么(即功能,整合或单元测试)。