Reputation: 4832
I have a simple class like
class SomeClass {
def foo() {
def bar= bar()
switch( bar ) {
return something based on format
}
}
def bar() {
return someValue
}
}
I've already written complete unit tests for the bar()
. Now I need to write unit tests for foo()
which is heavily dependant on the use of bar()
method. I don't want to duplicate the setup phase as done for bar()
, so I'd like to mock it by simply returning values I want.
I'm aware that Groovy supports this sort of "mocking" easily by simply defining it like SomeClass.property = "Hello World"
. Also, this can be done with collaborators as SomeClass.service = myMockedService
. But I've not found a way to accomplish this with methods inside the unit under tests. Is there?
I tried with MockFor
as in
def uut = new MockFor( SomeClass )
uut.demand.bar{ /* some values */ }
uut.use {
assert uut.foo() == expected
}
but it gives me
groovy.lang.MissingMethodException: No signature of method: groovy.mock.interceptor.MockFor.foo() is applicable for argument types: () values: []
UPDATE
In fact, I came up with a simple solution of using sub-classing. In the test method I create a subclass of SomeClass
where I override the method I wish to mock/stub. After this, using an instance of the subclass gives me what I need.
This seems a bit rough, though. Any other suggestions on this?
Upvotes: 0
Views: 2805
Reputation: 187399
If you want to mock the value returned by bar()
for a single instance of SomeClass
you can use metaprogramming. Try the following in the Groovy console:
class SomeClass {
def foo() {
}
def bar() {
return 'real value'
}
}
def uut = new SomeClass()
uut.metaClass.bar = {
return 'mock value'
}
assert 'mock value' == uut.bar()
If you want to mock bar()
for all instances of SomeClass
, replace this:
uut.metaClass.bar = {
return 'mock value'
}
with:
SomeClass.metaClass.bar = {
return 'mock value'
}
Upvotes: 3