简体   繁体   English

如何使用HtmlFormatter运行RSpec? 获取“私有方法`puts”调用nil:NilClass“

[英]How to run RSpec using HtmlFormatter? Getting “private method `puts' called for nil:NilClass”

I have a number of specs, which i wish to use in a Rails view (v3.2.15). 我有许多规范,我希望在Rails视图中使用(v3.2.15)。

I'm using the rspec-rails gem v2.14.0, and the code i run is below. 我正在使用rspec-rails gem v2.14.0,我运行的代码如下。

This code used to work on v2.11.4 of the gem and I can see HtmlFormatter has now had some of its code split out into HtmlPrinter , which i imagine has something to do with the error. 这段代码用于处理gem的v2.11.4,我可以看到HtmlFormatter现在已将其部分代码拆分为HtmlPrinter ,我想这与错误有关。 How are you meant to use HtmlFormatter ? 你打算如何使用HtmlFormatter I can't find any documentation beyond the source code... What am i doing wrong below? 我找不到源代码之外的任何文档......下面我做错了什么?

  class RSpecRunner
    attr_accessor :summary, :html, :documentation
    SpecPath = "system_checks/**/*_spec.rb"
    DataChecks = "data_checks/**/*_spec.rb"

    def initialize(path)
      @html = RSpec::Core::Formatters::HtmlFormatter.new(nil)
      @documentation = RSpec::Core::Formatters::DocumentationFormatter.new(nil)
    end

    def run!
      RSpec::world.reset
      Dir[@spec_path].each { |f| load f }

      @html = RSpec::Core::Formatters::HtmlFormatter.new(nil)
      reporter = RSpec::Core::Reporter.new(@html)

      RSpec::world.example_groups.each do |example_group|
        example_group.run(reporter)
      end
    end
  end

Controller 调节器

@sys_check = RSpecRunner.new(RSpecRunner::SystemChecksPath)
@sys_check.run!

View 视图

@sys_check.html.output.string

Error 错误

NoMethodError: private method `puts' called for nil:NilClass
    from /usr/lib/ruby/gems/1.9.1/gems/rspec-core-2.14.7/lib/rspec/core/formatters/html_printer.rb:23:in `print_example_group_start'
    from /usr/lib/ruby/gems/1.9.1/gems/rspec-core-2.14.7/lib/rspec/core/formatters/html_formatter.rb:50:in `example_group_started'
    from /usr/lib/ruby/gems/1.9.1/gems/rspec-core-2.14.7/lib/rspec/core/reporter.rb:127:in `block in notify'
    from /usr/lib/ruby/gems/1.9.1/gems/rspec-core-2.14.7/lib/rspec/core/reporter.rb:126:in `each'
    from /usr/lib/ruby/gems/1.9.1/gems/rspec-core-2.14.7/lib/rspec/core/reporter.rb:126:in `notify'
    from /usr/lib/ruby/gems/1.9.1/gems/rspec-core-2.14.7/lib/rspec/core/reporter.rb:74:in `example_group_started'
    from /usr/lib/ruby/gems/1.9.1/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:367:in `run'
    from (irb):11:in `block in irb_binding'
    from (irb):10:in `each'
    from (irb):10

Thanks 谢谢

The HtmlFormatter wants a way to output stuff. HtmlFormatter想要一种输出内容的方法。 Give it STDOUT: 给它STDOUT:

@html = RSpec::Core::Formatters::HtmlFormatter.new(STDOUT)

If you want the output to go to a file however, such as an HTML file, give it a file handle: 如果您希望输出转到文件,例如HTML文件,请为其指定文件句柄:

fh = File.open('path/to/html_output/rspec-html-output.html', 'w')
@html = RSpec::Core::Formatters::HtmlFormatter.new(fh)

Now you'll have a nice little html file of rspec's formatted output. 现在你将有一个很好的rspec格式输出的小html文件。

Edit: Whatever you pass to RSpec::Core::Formatters::HtmlFormatter.new needs to respond to puts and flush . 编辑:无论你传递给RSpec::Core::Formatters::HtmlFormatter.new需要响应putsflush

Since you want to save the output to accessors you can define those methods on your own custom classes that will save the output to the appropriate accessors :html and :documentation: 由于您希望将输出保存到访问器,因此您可以在自己的自定义类上定义这些方法,这些方法将输出保存到适当的访问器:html和:documentation:

class HTMLOutput
  def initialize(rspec_runner)
    @rspec_runner = rspec_runner
  end

  def puts(html)
    @rspec_runner.html ||= ""
    @rspec_runner.html << html
  end

  def flush; end
end

class DocOutput
  def initialize(rspec_runner)
    @rspec_runner = rspec_runner
  end

  def puts(html)
    @rspec_runner.documentation ||= ""
    @rspec_runner.documentation << html
  end

  def flush; end
end

class RSpecRunner
  def initialize(path)
    # I assumed you wanted to save the output of the formatter to the 
    # accessors :html and :documentation but you were already assigning
    # the formatters to these accessors via @html etc. Make new instance vars
    # for these and use the accessors just for the output.
    # By instantiating these output classes and passing in self they will be able
    # to save the output to the :html, :documentation accessors.
    @html_formatter = RSpec::Core::Formatters::HtmlFormatter.new(HTMLOutput.new(self))
    @documentation_formatter = RSpec::Core::Formatters::DocumentationFormatter.new(DocOutput.new(self))
  end

  ... rest of your code ...
end

Finally, in your runner's run! 最后,在你的跑步者的run! method you don't need to instantiate this guy again: 方法你不需要再次实例化这个人:

@html = RSpec::Core::Formatters::HtmlFormatter.new(nil)

Hope that helps. 希望有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM