Testing rake tasks with rspec

99 views
Skip to first unread message

Nicholas Wieland

unread,
Feb 12, 2014, 10:28:17 AM2/12/14
to rs...@googlegroups.com
Hi everyone, I'm having a very strange problem testing some rake tasks with rspec. I think I'm doing something terribly wrong here, and that's why rspec is having one of the weirdest behaviours I've ever seen...

Here is one of my rake tasks:

  namespace :rivendell do
    desc 'Outputs the current version of Rivendell'
    task version: :environment do
      puts Rivendell::VERSION
    end
  end

And here is my spec (paths are alright):

  describe 'Rakefile' do
    before :all do
      Rake.application.rake_require '../tasks/rivendell'
      Rake::Task.define_task :environment    
    end

    describe 'rivendell::version' do
      # This doesn't appear to work
      let :run_rake_task do
        Rake::Task["rivendell::version"].reenable
        Rake.application.invoke_task "rivendell::version"
      end
      it 'should display the right version' do
        Rivendell.should_receive('VERSION').and_return('0.1')
        run_rake_task
      end
    end
  end

With this version, all tests pass (I invoke it directly with the rspec command).
The problem is, if I change the should_receive call to should_receive('sdjkakja') it works as well, this suggests me I'm not testing my code but some kind of weird double I've created (no idea how, where or when).
I already posted on ruby-lang, I thought this place would be more appropriate.

TIA,
  ngw

Myron Marston

unread,
Feb 12, 2014, 11:11:37 AM2/12/14
to rs...@googlegroups.com
`Rivendell.should_receive(:VERSION)` will never work because `VERSION` is not a message `Rivendell` responds to.  VERSION is a constant nested under the `Rivendell` constant. RSpec has support for stubbing constants but it uses a different API:


HTH,
Myron 

Nicholas Wieland

unread,
Feb 13, 2014, 12:06:23 PM2/13/14
to rs...@googlegroups.com
Hi Myron, thanks for your answer, I didn't know. So if it doesn't answer to that message, why it doesn't fail? Honestly I'm not sure I get it.

Here is another rspec that should cover a "real" call to a "real" method:

  describe 'rivendell::get_account' do
    let :run_rake_task do
      Rake::Task["rivendell::get_account"].reenable
      Rake.application.invoke_task "rivendell::get_account"
    end
    it 'should generate an api key' do
      Rivendell::Models::Apikey.should_receive(:create)
      run_rake_task
    end
  end
 
This is the rake task:

  desc 'Setup a user account'
  task get_account: :environment do
    begin
      if ENV['TOKEN'] && ENV['SECRET']
        api_key = Rivendell::Models::Apikey.create(token: ENV['TOKEN'], secret: ENV['SECRET'])
      else
        api_key = Rivendell::Models::Apikey.create
      end
      puts "Account created: \n\tTOKEN: #{api_key.token} \n\tSECRET: #{api_key.secret}"
    rescue => msg
      puts "Something didn't work as expected: \n\t#{msg}"
    end
  end

If I change the call to Rivendell::Models::Apikey.should_receive(:sdhfkjshd) it still passes. Seems to me whatever I do
all my specs pass, which is great for my ego, not so much for my code ;)

TIA,
  ngw

Reply all
Reply to author
Forward
0 new messages