Need help mocking out a method

I’m trying to test a controller method’s error handling. To do so I
need to mock out a method that normally returns a unique number so
that it returns a duplicate number several times in a row thereby
triggering the error handling. However, I can’t get the mock working.
Here’s the test code along with the error (all from test/functional/
storage_api_test.rb).

class StorageController
@mock_uuid = [“7cd00940-df96-0128-85c8-000a95ba12c4”,
“cca3c300-df8f-0128-85c8-000a95ba12c4”,
“cca3c300-df8f-0128-85c8-000a95ba12c4”,
“cca3c300-df8f-0128-85c8-000a95ba12c4”,
“cca3c300-df8f-0128-85c8-000a95ba12c4”]

def get_next_uuid
@mock_uuid.shift
end
end

class StorageControllerApiTest < Test::Unit::TestCase
[big snip of standard stuff]

def test_assign_uuid
a = @controller.get_next_uuid
# fails before assertion
end
end

cremes$ ruby test/functional/storage_api_test.rb -n test_assign_uuid
Loaded suite test/functional/storage_api_test
Started
E
Finished in 0.074318 seconds.

  1. Error:
    test_assign_uuid(StorageControllerApiTest):
    NoMethodError: You have a nil object when you didn’t expect it!
    You might have expected an instance of Array.
    The error occured while evaluating nil.shift
    test/functional/storage_api_test.rb:16:in get_next_uuid' test/functional/storage_api_test.rb:275:intest_assign_uuid’

1 tests, 0 assertions, 0 failures, 1 errors

(BTW, I understand that this functionality should probably live in
one of the models used by this controller. I plan to move it there
during my next refactoring session.)

I thought I was doing this correctly by reopening my
StorageController class and redefining the #get_next_uuid method.
What am I doing wrong and how should I fix it?

cr

On Jun 16, 2006, at 12:17 PM, [email protected] wrote:

  "cca3c300-df8f-0128-85c8-000a95ba12c4",
  "cca3c300-df8f-0128-85c8-000a95ba12c4",
  "cca3c300-df8f-0128-85c8-000a95ba12c4"]

cr
Hey

The problem you are having is a scope issue. When you are setting

@mock_uuid outside of a method, you are creating an instance variable
on the class object itself and not the instance. So put your
declaration in a before filter instead and you will be fine:

class StorageController

 before_filter :setup_uuid

 def setup_uuid
   @mock_uuid = ["7cd00940-df96-0128-85c8-000a95ba12c4",
     "cca3c300-df8f-0128-85c8-000a95ba12c4",
     "cca3c300-df8f-0128-85c8-000a95ba12c4",
     "cca3c300-df8f-0128-85c8-000a95ba12c4",
     "cca3c300-df8f-0128-85c8-000a95ba12c4"]
 end
 protected :setup_uuid

#other coded
end

Cheers-
-Ezra

On Jun 16, 2006, at 2:46 PM, Ezra Z. wrote:

cr

Hey

The problem you are having is a scope issue. When you are setting
@mock_uuid outside of a method, you are creating an instance
variable on the class object itself and not the instance. So put
your declaration in a before filter instead and you will be fine:

[snip code]

I tried this and I still get the same error.

  1. Error:
    test_assign_uuid(StorageControllerApiTest):
    NoMethodError: You have a nil object when you didn’t expect it!
    You might have expected an instance of Array.
    The error occured while evaluating nil.shift
    /Volumes/spaceman/cremes/developer/projects/ruby/rails/rogilefs/
    config/…/test/mocks/test/storage_controller.rb:16:in get_next_uuid' test/functional/storage_api_test.rb:284:intest_assign_uuid’

The exact code is:

require ‘controllers/storage_controller’

class StorageController
before_filter :setup_uuid

def setup_uuid
@mock_uuid = [“7cd00940-df96-0128-85c8-000a95ba12c4”,
“cca3c300-df8f-0128-85c8-000a95ba12c4”,
“cca3c300-df8f-0128-85c8-000a95ba12c4”,
“cca3c300-df8f-0128-85c8-000a95ba12c4”,
“cca3c300-df8f-0128-85c8-000a95ba12c4”]
end
protected :setup_uuid

def get_next_uuid
@mock_uuid.shift
end
end

And back in the actual functional test itself…

def test_assign_uuid
a = @controller.get_next_uuid
end

I also have flexmock installed and made a (separate) attempt to use
it to replace the UUID object that creates these values.
Unfortunately I can’t seem to mock a class that has no instance
methods; they are all class methods (e.g. UUID.new returns a string
instead of a uuid instance object.) If I could figure out how to mock
that object (the gem uuid) then I could eliminate mocking out this
method call. I would actually prefer to do it this way since I have
other tests that, as a side effect, call #get_next_uuid and I would
prefer those calls to be through the real method and not the mocked one.

Thanks for any further help.

cr