测试此rails控制器 - 在进行API调用时?

时间:2014-07-30 23:04:13

标签: ruby-on-rails api rspec

我对测试并不陌生。我为自己感到自豪,有97% - 100%的测试覆盖率。事实上,95%以下的任何东西都很差(但这不是主题)。我有以下rails控制器:

module Api
  module Internal
    class TwitterController < Api::V1::BaseController

      # Returns you 5 tweets with tons of information.
      #
      # We want 5 specific tweets with the hash of #AisisWriter.
      def fetch_aisis_writer_tweets
        tweet_array = [];
        tweet = twitter_client.search("#AisisWriter").take(5).each do |tweet|
          tweet_array.push(tweet)
        end

        render json: tweet_array
      end

      private

      # Create a twitter client connection.
      def twitter_client
        client = Twitter::REST::Client.new do |config|
          config.consumer_key               = ENV['CONSUMER_KEY']
          config.consumer_secret            = ENV['CONSUMER_SECRET_KEY']
          config.access_token               = ENV['ACCESS_TOKEN']
          config.access_token_secret        = ENV['ACCESS_TOKEN_SECRET']
        end
      end

    end
  end
end

看到最新情况,这是非常基本的。现在我可以编写rspec测试来说出这个动作,I expect json['bla']['text'] to eql bla

但是有几个问题。为了有效地测试这个,您需要twitter API凭据。这就是我的代码与我希望启动并运行的另一项服务的结合。

事实上,我的控制器基本上与推特耦合。

所以 - 我的问题是,不必嘲笑网络服务或api电话(我已经看到了一些关于此的博客文章,对于这段代码,我觉得他们已经过度杀戮) - 怎么会你测试一下吗?

有些人建议录像机。有关测试API调用的任何想法都是这样的吗?

1 个答案:

答案 0 :(得分:1)

我发现VCR是这类测试的绝佳工具 - 您不需要对外部服务返回的内容进行大量控制,因为您不需要有很多案例需要测试。您只是想根据服务是否已启动来消除测试片状,并且您希望确保每次都获得完全相同的假响应。我根本不会说VCR太过分了,使用非常简单 - 只需将测试包装在use_cassette块中,运行测试,VCR记录服务的实际响应并将其用作当时的模拟回应。

我会说&#34;录音带&#34; VCR用于存储模拟响应的是相当复杂的YAML,并且它们不具有超级可读/易编辑性。如果您希望能够轻松地操作返回的数据,以便您可以测试多个代码路径,并轻松阅读它,以便您的模拟数据可以作为代码的文档,我会调查更像是HttpMock

当然,另一个选择是将调用外部服务的私有方法存根,并让它直接返回模拟数据。通常我会避免这种情况,因此您可以重构您的私有方法并仍然被覆盖,但在某些情况下,私有方法很简单并且不太可能发生变化,这可能是一种选择,并且将其删除会显着清洁测试。