0

Ruby on Rails を使用してブログ用のアプリケーションに取り組んでいます。Draper Decorator を使用した Essay というモデルがあります。このアプリケーションのテストには MiniTest::Spec も使用しています。各エッセイには本文があり、Markdown として保存されます。EssayDecorator には、RedCarpet を使用して Markdown を html にレンダリングする body というメソッドがあります。

この方法をテストするために、次のコードを書きました。

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

デコレータ内には、次の 2 つのメソッドがあります。

  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 でこの種のものをモックアウトするためのベスト プラクティスはありますか? 私はモックを使用するのはかなり初めてで、MiniTest を使用するのは非常に初めてです。

前もって感謝します。

4

1 に答える 1

0

IMO このコードは、コードの動作をテストしているのではなく、実装をテストしているため、奇妙に思えます。実装が変更された場合 (HTML を Redcarpet で実行する代わりにキャッシュに保存した場合)、このテストは失敗します。これは私には過度に嘲笑されているように見えます。

RedCarpet が機能していることをテストするのではなく、render メソッドを呼び出していることをテストしたいだけです。

これが実装です。なぜマークダウンを介してボディを実行しているのですか? URL からハイパーリンクを作成したいからですか? そのためのテストを作成します。リンクに no-follow 属性があることを確認したいですか? そのためのテストを作成します。コードが何かを行う方法ではなく、なぜコードが何かを行うのかについてのテストを作成します。

アプリケーションで抽象化が欠落している可能性も十分にあります。プレーン テキストを HTML にフォーマットする役割を担うもの。Redcarpet、RDiscount、または重要と見なされるその他のライブラリを使用するもの。EssayDecorator は、テキストが適切に書式設定されていることを確認する責任を負うべきではありませんが、適切なオブジェクトに書式を適用するように指示する責任がある場合があります。

于 2013-09-10T23:08:28.977 に答える