我是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
我正在编写一个单元测试用例来测试user_profile.save何时失败,测试用例期望引发异常。但是在我的user_profiles表中,我只有一列:name。
如何在user_profile.save失败时测试案例? 这里最重要的问题是我找不到任何方法让这个user_profile.save失败。
有人建议使用RSpec Stubs。我们怎么做?
答案 0 :(得分:2)
根据Rspec的预期,当您预期会出现错误时,您会有一种特殊的语法。
如果你做了这样的事情:
private static RequestQueue mRequestQueue;
public RequestQueue getRequestQueue()
{
if (mRequestQueue == null) {
Cache cache = new DiskBasedCache(MTXApplication.getAppContext().getCacheDir(), 20 * 1024 * 1024);
Network network = new BasicNetwork(new HurlStack());
mRequestQueue = new RequestQueue(cache, network);
mRequestQueue.start();
}
return mRequestQueue;
}
这不起作用 - RSpec不会处理错误并退出。
但是如果使用括号:
expect(raise NoMethodError).to raise_error(NoMethodError)
应该通过。
如果你使用括号(或do / end块),那么块中的任何错误都将被“捕获”,你可以使用expect { raise NoMethodError }.to raise_error(NoMethodError)
匹配器进行检查。
答案 1 :(得分:0)
结账rspec文件:
https://www.relishapp.com/rspec/rspec-expectations/v/2-11/docs/built-in-matchers/raise-error-matcher
describe ':: create_from_supplement' do
it 'blows up' do
expect { UserProfile.create_from_supplement(*args) }.to raise_error(/User Profile Creation Failed because of/)
end
end
追溯您的代码,以下是可能导致错误的地方,并遵循您可以考虑的内容。
user_details_str = xml.%('auth_supplement/supplement_data/content').inner_html
此处user_details_str
可能是无效的字符串格式(不是nil),因为从'auth_supplement/supplement_data/content'
获得的内容格式不正确。
user_details_xml = Nokogiri.parse(user_details_str)
在这里,您需要确定可能导致Nokogiri::parse
给您无效结果的原因。
user_name = user_details_xml.%('username').inner_html
然后在这里,与上面相同。
user_profile = UserProfile.find_or_initialize_by(name: user_name)
所以在这里,由于之前的几行代码,您可能会有一个无效的user_name
,这违反了您可能拥有的任何验证(例如,太短,没有大写,或者没有)。
更多信息
因此,这可以深入到您的代码中。很难测试,因为你的方法试图做太多。这显然违反了abc大小(逻辑分支太多,这里有更多信息:http://wiki.c2.com/?AbcMetric)
我建议将此方法的某些分支重构为较小的单一责任方法。