测试服务类 - Rails

时间:2014-05-23 12:51:39

标签: ruby-on-rails oop unit-testing testing rspec

我想知道你们如何在Rails中测试服务对象类?让我们说用户注册。在数据库中创建用户,将其添加到电子邮件列表中,并发生其他事情。你是如何测试的?

class UserRegistrar
  def sign_up(user)
    User.create(user) # or something to this effect
    EmailMarketing.add_to_email_list(user)
    SuperSecretClass.do_secret_stuff(user)
    LoggingThing.new.log_stuff_about(user)
  end
end

(控制者行动)

def create
    UserRegistrar.sign_up(params)
    # stuff for the strong params, etc...
end

我所做的就是确保使用正确的参数调用方法。方法的结果(如确保用户确实已添加到列表中)在各自的类中进行测试。我做得对吗?

2 个答案:

答案 0 :(得分:1)

在测试中存在断言所有内容的危险,因为那时你只是测试该类适合测试,而不是适应其余的代码。如果EmailMarketing.add_to_email_list一天在重构中变为EmailMarketing.add_to(:email_list ...),那么您的测试就无法进行重构。

您可以使用User作为示例来测试代码的效果:

expect {
  UserRegistrar.sign_up(user)
}.to change{
  user.persisted?
}.from(false).to(true)

答案 1 :(得分:1)

是的,如果我需要为你所展示的课程编写一个单元测试,我会按照你所说的方式进行模拟测试。在您的示例中,所有工作都委托给高级模型方法,这些方法需要自己的测试,并且可能在多个地方使用,因此在测试中测试这些方法的功能是没有意义的。的服务。并没有那么多的模拟方法调用,所以它不会太痛苦。

然而,

  • 如果这些模型方法中的任何一种仅在一项服务中使用,我会考虑将这些方法移到服务中以缩小模型并使服务更加连贯。如果我最终得到了自己做了大量工作的服务方法,而不仅仅是委托,我会通过创建数据库对象并断言服务如何更改它们来测试服务测试中的功能。

  • 另一方面,如果我有一个只委托的服务,它可能已经通过我的验收测试完全测试(因为我正在做BDD并首先编写验收测试),并且会有根本不需要对服务进行单元测试。