期望在rspec中多次改变期望

时间:2016-04-19 16:11:14

标签: ruby-on-rails rspec capybara

我正在尝试通过一个操作确保某些数据保持不变:

expect {
  # running migration and user reload here
}.not_to change(user, :avatar_url).from(sample_avatar_url).and change(user, :old_avatar).from(nil)

sample_avatar_url是在spec文件开头定义的字符串。

基本上,我想检查avatar_urlold_avatar是否仍然不受expect块中发生的事情的影响。

以上代码的输出是:

  不支持

expect(...).not_to matcher.and matcher,因为它会产生一些歧义。相反,使用RSpec::Matchers.define_negated_matcher定义您希望否定的任何匹配器的否定版本并使用expect(...).to matcher.and matcher

2 个答案:

答案 0 :(得分:16)

这不起作用,因为它不清楚读取是否应该意味着不改变第一个而不是改变第二个,或者不改变第一个但改变第二个。你有几个选择来解决这个问题

由于您正在检查静态值,因此不要使用更改

<activity
    android:name="MainActivity"
    android:label="@string/app_name"
    android:theme="@style/splashScreenTheme" >

或使用define_negated_matcher创建not_change匹配器

..run migration and user reload..
expect(user.avatar_url).to eq(sample_avatar_url)
expect(user.old_avatar).to eq nil

答案 1 :(得分:0)

如Thomas所述,它不起作用,因为它不清楚阅读,你可以创建一个否定的匹配器。另一种选择是使用saharspec gem及其dont匹配器否定。

以下是项目自述文件的摘录:

  

另一个(实验性的)企图摆脱define_negated_matcherdont不是100%语法正确,但简短且可读。它只是否定附加的匹配器。

# before
RSpec.define_negated_matcher :not_change, :change

it { expect { code }.to do_stuff.and not_change(obj, :attr) }

# after: no `define_negated_matcher` needed
require 'saharspec/matchers/dont'

it { expect { code }.to do_stuff.and dont.change(obj, :attr) }

所以你可以写下你的期望,而不是像这样创建一个否定的匹配器:

expect {
  # running migration and user reload here
}.to dont.change(user, :avatar_url).from(sample_avatar_url).and 
    dont.change(user, :old_avatar).from(nil)