RSpec 用于测试 Rails 中引发异常

kri*_*hna 1 ruby rspec ruby-on-rails exception

我是 RSpec 的新手。我的模型 user_profile.rb 中有一个方法

def self.create_from_supplement(device, structure)
  xml = Nokogiri.parse(structure.to_s)
  user_profile = nil
  auth_type = xml.%('auth_supplement/auth_type').inner_html

  if 'user' == auth_type
    user_details_str = xml.%('auth_supplement/supplement_data/content').inner_html rescue nil

    return nil if user_details_str.blank?

    user_details_xml = Nokogiri.parse(user_details_str)
    user_name = user_details_xml.%('username').inner_html

    user_profile = UserProfile.find_or_initialize_by(name: user_name)

    if user_profile.save
      device.update_attributes(user_profile_id: user_profile.id)
    else
      raise "User Profile Creation Failed because of #{user_profile.errors.full_messages}"
    end

  end

  return user_profile
end
Run Code Online (Sandbox Code Playgroud)

我正在编写一个单元测试用例来测试当 user_profile.save 失败时,测试用例将期望引发异常。但在我的 user_profiles 表中我只有一列:名称。

user_profile.save失败时如何测试? 这里最重要的问题是我找不到任何方法使这个 user_profile.save 失败。

有些人建议使用 RSpec 存根。我们该怎么做呢?

max*_*ner 6

通过 Rspec 期望,当您期望引发错误时,您可以使用特殊的语法。

如果你做了这样的事情:

expect(raise NoMethodError).to raise_error(NoMethodError)
Run Code Online (Sandbox Code Playgroud)

这是行不通的 - RSpec 不会处理错误并且会退出。

但是,如果您使用括号:

expect { raise NoMethodError }.to raise_error(NoMethodError)
Run Code Online (Sandbox Code Playgroud)

那应该过去了。

如果您使用括号(或 do / end 块),则块中的任何错误都将被“捕获”,您可以使用匹配器检查它们raise_error