在MiniTest中测试对外部库的调用

时间:2013-09-10 01:41:58

标签: ruby-on-rails ruby mocking minitest

我正在使用Ruby on Rails开发博客应用程序。我有一个名为Essay的模型,带有Draper装饰器。我也使用MiniTest :: Spec来测试这个应用程序。每篇论文都有一个将被存储为Markdown的正文。在EssayDecorator中,我有一个名为body的方法,它使用RedCarpet将Markdown渲染为html。

为了测试这个方法,我编写了以下代码:

describe '#body' do
  it 'returns html from the markdown' do
    essay = FactoryGirl.create(:essay)
    @decorated_essay = essay.decorate
    markdown = Minitest::Mock.new 

    @decorated_essay.stub :markdown, markdown do
      markdown.expect :render, "<p>Test</p>", [essay.body]
      @decorated_essay.send(:body)
      markdown.verify
    end
  end
end

在装饰者里面我有两种方法:

  def body
    markdown.render(model.body).html_safe
  end

  def markdown
    Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true)
  end

这个测试通过,但对我来说似乎很奇怪。我不想测试RedCarpet正在做它的工作,我只想测试我调用render方法。

在MiniTest中嘲笑这种东西是否有最好的做法?我是使用Mocks的新手,也是使用MiniTest的新手。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

IMO这段代码看起来很奇怪,因为它不是测试代码的行为,而是测试实现。如果实现发生了变化(您将HTML存储在缓存中而不是通过Redcarpet运行),那么此测试将失败。这看起来过于嘲笑我。

  

我不想测试RedCarpet正在做它的工作,我只想测试我调用render方法。

这是实施。你为什么要通过降价运动身体?因为您想要从URL创建超链接?我会为此创建一个测试。您想确保链接具有no-follow属性吗?我会为此创建一个测试。为代码执行某些操作而不是如何执行操作创建测试。

您完全有可能在应用程序中缺少抽象。负责将纯文本格式化为HTML的东西。使用Redcarpet或RDiscount或任何其他被认为重要的库的东西。 EssayDecorator可能不应该负责确保文本格式正确,但它可能负责告诉正确的对象应用格式。