【问题标题】:Rspec Ruby MockingRspec Ruby 模拟
【发布时间】:2013-06-20 03:04:25
【问题描述】:

我想在一个模块上实现 100% 的覆盖率。我的问题是在我试图注入数据以测试我的异常处理的方法中有一个变量(称为数据)。这可以通过嘲笑来完成吗?如果不是,我该如何全面测试我的异常处理?

module CSV
  module Extractor
class ConversionError   < RuntimeError; end
class MalformedCSVError < RuntimeError; end
class GenericParseError < RuntimeError; end 
class DemoModeError     < RuntimeError; end

def self.open(path)
  data = `.\\csv2text.exe #{path} -f xml --xml_output_styles 2>&1`
  case data
  when /Error: Wrong input filename or path:/
    raise MalformedCSVError, "the CSV path with filename '#{path}' is malformed"
  when /Error: A valid password is required to open/
    raise ConversionError, "Wrong password: '#{path}'"
  when /CSVTron CSV2Text: This page is skipped when running in the demo mode./
    raise DemoModeError, "CSV2TEXT.exe in demo mode"
  when /Error:/
    raise GenericParseError, "Generic Error Catch while reading input file"
  else
    begin
      csvObj = CSV::Extractor::Document.new(data)
    rescue
      csvObj = nil
    end
    return csvObj
  end  
end
end
end

让我知道你的想法!谢谢

======================编辑========================

我已将我的方法修改为您建议的设计模式。这个方法-"open(path)" 负责捕获和引发错误,get_data(path) 只是返回数据,就是这样!但不幸的是,在 rspec 中,我得到“预计会引发异常,但没有引发任何异常”。我想也许我们也必须从你的存根调用 open 方法?

这是我尝试做的,但仍然没有出现错误..

    it 'should catch wrong path mode' do
    obj = double(CSV::Extractor)
    obj.stub!(:get_data).and_return("Error: Wrong input filename or path:")
    obj.stub!(:open)
    expect {obj.open("some fake path")}.to raise_error CSV::Extractor::MalformedCSVError
    end

【问题讨论】:

  • 你指的是“数据”变量吗?

标签: ruby unit-testing rspec mocking


【解决方案1】:

提取将数据返回到单独方法的代码。然后,当您测试open 时,您可以存根该方法以返回各种字符串,这些字符串将执行case 语句的不同分支。设置大致是这样的:

def self.get_data(path)
  `.\\csv2text.exe #{path} -f xml --xml_output_styles 2>&1`
end

def self.open(path)
  data = get_data(path)
  ...

我假设你知道如何stub methods in rspec,但总体思路是这样的:

foo = ...
foo.stub(:get_data).and_return("Error: Wrong input filename or path:")
expect { foo.get_data() }.to raise_error MalformedCSVError

另请参阅testing for exceptions 上的 Rspec 文档。

【讨论】:

  • 这听起来像是正确的方法。同时,我对存根非常陌生。您是否可以在示例中添加更多内容来演示您提出的带有存根的解决方案?
  • @user1438150 不要存根open——如果你这样做,你的代码将不会运行,也不会引发异常。只需存根get_data
【解决方案2】:

测试模块的问题在于您设计代码的方式。考虑将提取器分成两个类(或模块,这取决于口味——我会选择类,因为它们更容易测试),其中一个会从外部系统调用中读取数据,第二个会期望这些数据作为参数传递。

通过这种方式,您可以轻松地模拟您当前在 data 变量中拥有的内容,因为这将作为参数简单地传递(无需考虑此处的实现细节!)。

为了更容易使用,您可以稍后提供一些包装调用,这将创建两个对象并将一个作为参数传递给另一个。请注意,此行为也可以轻松测试。

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    相关资源
    最近更新 更多