Reputation:
I'm new to testing in Grails, so I'm not sure if I'm taking the correct approach. I am trying to unit test a service (call it FooService) that has an instance of another class (call it Bar) as a property. Basically something like:
class FooService {
Bar bar
void afterPropertiesSet() {
bar = new Bar()
}
}
So, I'm trying to test the afterPropertiesSet method, and as I understand it, the correct practice for unit tests is to mock outside classes. So, how, in FooServiceTests extends GrailsUnitTestCase, do I mock the Bar constructor?
Thanks
Upvotes: 1
Views: 2385
Reputation: 51
Answering too late , but if somebody wants in future.
def barObj
def barCtrl= mockFor(Bar )
Bar.metaClass.constructor = { ->
barObj=[:]
return barObj
}
when:
service.afterPropertiesSet()
then:
assert barObj == //check the properties
Upvotes: 2
Reputation: 16380
If you do need or want to mock the Bar
constructor, you can.
Using JMockit, you could write (in Java below, see here about using it with Groovy):
import org.junit.*;
import org.junit.runner.*;
import mockit.*;
import mockit.integration.junit4.*;
@RunWith(JMockit.class)
public class FooServiceTest
{
@Test
public void afterPropertiesSet()
{
new Expectations()
{
Bar mockBar;
{
new Bar(); // records expectation for the Bar constructor
}
};
// Will call a mocked "Bar()":
new FooService().afterPropertiesSet();
}
}
Upvotes: 0
Reputation: 308813
You don't.
EasyMock depends on proxies, and that means an interface. Unless Bar can be an interface, it's not a candidate for proxying.
You'd mock something like a DAO or another external dependency that you've already unit tested to keep your FooServiceTest from becoming an integration test, but Bar? No.
"...the correct practice for unit tests is to mock outside classes..." - I believe this is incorrect. Mocking for every object takes the idea too far.
Upvotes: 0