title: Minitest: How to stub/mock the file result of Kernel.open on a URL
body: <p>I have been trying to use Minitest to test my code (<a href="https://github.com/kkirsche/elasticsearch_update" rel="nofollow">full repo</a>) but am having trouble with one method which downloads a SHA1 hash from a .txt file on a website and returns the value.</p>
  
  <p>Method:</p>
  
  <pre><code>def download_remote_sha1
    @log.info('Downloading Elasticsearch SHA1.')
  
    @remote_sha1 = ''
    Kernel.open(@verify_url) do |file|
      @remote_sha1 = file.read
    end
  
    @remote_sha1 = @remote_sha1.split(/\s\s/)[0]
  
    @remote_sha1
  end
  </code></pre>
  
  <p>You can see that I log what is occurring to the command line, create  an object to hold my SHA1 value, open the url (e.g. <a href="https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.2.deb.sha1.txt" rel="nofollow">https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.2.deb.sha1.txt</a>)</p>
  
  <p>I then split the string so that I only have the SHA1 value.</p>
  
  <p>The problem is that during a test, I want to stub the <a href="http://www.ruby-doc.org/stdlib-2.1.5//libdoc/open-uri/rdoc/Kernel.html#method-c-open" rel="nofollow"><code>Kernel.open</code></a> which uses OpenURI to open the URL. I would like to ensure that I'm not actually reaching out to download any file, but rather I'm just passing the block my own mock IO object testing just that it correctly splits stuff.</p>
  
  <p>I attempted it like the block below but when <code>@remote_sha1 = file.read</code> occurs the file item is nil.</p>
  
  <pre><code>@mock_file = Minitest::Mock.new
  @mock_file.expect(:read, 'd377e39343e5cc277104beee349e1578dc50f7f8  elasticsearch-1.4.2.deb')
  
  Kernel.stub :open, @mock_file do
    @downloader = ElasticsearchUpdate::Downloader.new(hash, true)
    @downloader.download_remote_sha1.must_equal 'd377e39343e5cc277104beee349e1578dc50f7f8'
  end
  </code></pre>