RSpec:期望更改多个 [英] RSpec: Expect to change multiple

查看:26
本文介绍了RSpec:期望更改多个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在提交功能规范中的表单时检查模型中的许多更改.例如,我想确保用户名从 X 更改为 Y,并且加密的密码更改为任意值.

I want to check for many changes in a model when submitting a form in a feature spec. For example, I want to make sure that the user name was changed from X to Y, and that the encrypted password was changed by any value.

我知道已经有一些关于此的问题,但我没有找到适合我的答案.最准确的答案似乎是 Michael Johnston 的 ChangeMultiple 匹配器:RSpec 是否可以预期两个表中的变化?.它的缺点是只能检查从已知值到已知值的显式变化.

I know there are some questions about that already, but I didn't find a fitting answer for me. The most accurate answer seems like the ChangeMultiple matcher by Michael Johnston here: Is it possible for RSpec to expect change in two tables?. Its downside is that one only check for explicit changes from known values to known values.

我创建了一些伪代码来说明我认为更好的匹配器的外观:

I created some pseudo code on how I think a better matcher could look like:

expect {
  click_button 'Save'
}.to change_multiple { @user.reload }.with_expectations(
  name:               {from: 'donald', to: 'gustav'},
  updated_at:         {by: 4},
  great_field:        {by_at_leaset: 23},
  encrypted_password: true,  # Must change
  created_at:         false, # Must not change
  some_other_field:   nil    # Doesn't matter, but want to denote here that this field exists
)

我也像这样创建了 ChangeMultiple 匹配器的基本框架:

I have also created the basic skeleton of the ChangeMultiple matcher like this:

module RSpec
  module Matchers
    def change_multiple(receiver=nil, message=nil, &block)
      BuiltIn::ChangeMultiple.new(receiver, message, &block)
    end

    module BuiltIn
      class ChangeMultiple < Change
        def with_expectations(expectations)
          # What to do here? How do I add the expectations passed as argument?
        end
      end
    end
  end
end

但现在我已经收到此错误:

But now I'm already getting this error:

 Failure/Error: expect {
   You must pass an argument rather than a block to use the provided matcher (nil), or the matcher must implement `supports_block_expectations?`.
 # ./spec/features/user/registration/edit_spec.rb:20:in `block (2 levels) in <top (required)>'
 # /Users/josh/.rvm/gems/ruby-2.1.0@base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
 # /Users/josh/.rvm/gems/ruby-2.1.0@base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'

非常感谢您对创建此自定义匹配器的任何帮助.

Any help in creating this custom matcher is highly appreciated.

推荐答案

在 RSpec 3 中,您可以一次设置多个条件(因此单一期望规则不会被破坏).它看起来像:

In RSpec 3 you can setup multiple conditions at once (so the single expectation rule is not broken). It would look sth like:

expect {
  click_button 'Save'
  @user.reload
}.to change { @user.name }.from('donald').to('gustav')
 .and change { @user.updated_at }.by(4)
 .and change { @user.great_field }.by_at_least(23}
 .and change { @user.encrypted_password }

虽然这不是一个完整的解决方案 - 就我的研究而言,还没有简单的方法可以做到 and_not.我也不确定你上次的检查(如果它无关紧要,为什么要测试它?).当然,您应该能够将它包装在您的 自定义匹配器.

It is not a complete solution though - as far as my research went there is no easy way to do and_not yet. I am also unsure about your last check (if it doesn't matter, why test it?). Naturally you should be able to wrap it within your custom matcher.

这篇关于RSpec:期望更改多个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆