views:

255

answers:

4

I'm having a lot of trouble trying to define a mock for a rails models on cucumber. It seems like the method is creating a bunch of message expectations and i keep getting errors like these:

 Given I have only a product named "Sushi de Pato" # features/step_definitions/product_
steps.rb:19
      unexpected invocation: #<Mock:ProductCategory_1001>.__mock_proxy()
      unsatisfied expectations:
      - expected exactly once, not yet invoked: #<Mock:ProductCategory_1001>.errors(any_pa
rameters)
      - expected exactly once, not yet invoked: #<Mock:ProductCategory_1001>.id(any_parame
ters)
      - expected exactly once, not yet invoked: #<Mock:ProductCategory_1001>.to_param(any_
parameters)
      - expected exactly once, not yet invoked: #<Mock:ProductCategory_1001>.new_record?(a
ny_parameters)
      - expected exactly once, not yet invoked: #<Mock:ProductCategory_1001>.destroyed?(an
y_parameters)
      satisfied expectations:
      - allowed any number of times, not yet invoked: #<Mock:errors>.count(any_parameters)

       (Mocha::ExpectationError)

I haven't yet implemented the ProductCategory class and I just want it to return an ID and a 'name' attribute.

This is my step definition:

Given /^I have only a product named "([^\"]*)"$/ do |name|
  @product = Product.create!(:name => name, :description => 'Foo', :price => 100, :points => 100, :category => mock_model(ProductCategory))
end

And this is my env.rb file:

$: << File.join(File.dirname(__FILE__),"..")

require 'spec\spec_helper

I am using RSPec 1.3.0, cucumber 0.6.3 and webrat 0.7.0

I've tried to use stubs as well but got some other errors instead...

A: 

It's really not recommended to mock models in cucumber. Cucumber is intended to be a full stack, outside-in testing framework.

If you haven't yet implemented the ProductCategory class, I'd recommend removing the category association from Product and just test the functionality you've implemented.

When you get around to implementing ProductCategory, you can test drive it through then.

jrallison
I think you're absolutely right! After reading a lot of stuff on the web about cucumber trying to solve this problem, i came to this conclusion that cucumber should act more as an integration test, thereby needing every stuff i describe to be implemented. I've solved it by creating the ProductCategory model spec and then implementing it. I think it makes sense since Product and ProductCategory are intimately connected.thank you very much!
Lucas d. Prim
A: 

I think jrallison answered the question but anyway, if you feel like mocking models on cucumber for implementing behaviour for things like external connections or date/time manipulation, you can use the following answer that i got from a fellow programmer at the cukes discussion list:

Here is what I do in env.rb: require "spec/mocks"

Before do
 # To get RSpec stubs and mocks working.
 $rspec_mocks ||= Spec::Mocks::Space.new
end

After do
   begin
     $rspec_mocks.verify_all
   ensure
     $rspec_mocks.reset_all
   end
end

Good luck!

Lucas d. Prim
A: 

I am too getting the similar error, but I am mocking out the user in Controller tests.

When you say env.rb which file do you mean ? is it config/environment.rb or config/environments/test.rb.

I tried adding in both test.rb and environment.rb, but it didn't work for me.

I am still getting this error.

/home/xuser/myprojects/xproject/spec/routing/../spec_helper.rb:9: undefined method `Before' for main:Object (NoMethodError)
from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /home/xuser/myprojects/xproject/vendor/rails/activesupport/lib/active_support/dependencies.rb:158:in `require'
from /home/xuser/myprojects/xproject/spec/routing/routes_spec.rb:1
from /home/xuser/myprojects/xproject/vendor/rails/activesupport/lib/active_support/dependencies.rb:147:in `load_without_new_constant_marking'
from /home/xuser/myprojects/xproject/vendor/rails/activesupport/lib/active_support/dependencies.rb:147:in `load'
from /home/xuser/myprojects/xproject/vendor/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:15:in `load_files'
from /home/xuser/myprojects/xproject/vendor/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:14:in `each'
from /home/xuser/myprojects/xproject/vendor/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:14:in `load_files'
from /home/xuser/myprojects/xproject/vendor/gems/rspec-1.3.0/lib/spec/runner/options.rb:133:in `run_examples'
from /home/xuser/myprojects/xproject/vendor/gems/rspec-1.3.0/lib/spec/runner/command_line.rb:9:in `run'
Amiruddin Nagri
Actually env.rb is features/support/env.rb - this file is used by cucumber to set up its environment before it runs! it worked perfectly for me!
Lucas d. Prim
A: 

In my case, it was because I activated another mocking framework and I forgot about that. I fixed it by commenting again than line in spec/spec_helper.rb:

  # == Mock Framework
  #
  # RSpec uses its own mocking framework by default. If you prefer to
  # use mocha, flexmock or RR, uncomment the appropriate line:
  #
  # config.mock_with :mocha
  # config.mock_with :flexmock
  # config.mock_with :rr

That way RSpec will use its own mocking framework