I'm having some difficulty with EasyMock (3.1) class mocking. This is supposedly suitable to mock partial class implementations, which, I figured, should be ideal to unit test abstract base classes while mocking out the missing method(s). Here's the pattern - an instantly recognizable classic...
public interface Interface {
public void intfMethod();
}
public abstract class AbstractBase implements Interface {
public void otherMethod() {
// do some stuff we need to test...
intfMethod();
}
}
Now the test:
public class TestAbstractBase {
AbstractBase testInstance;
#Before
public void setUp() {
testInstance =
createMockBuilder(AbstractBase.class).addMockedMethod("intfMethod").createMock();
}
#Test
public void testOtherMethod() {
testInstance.intfMethod(); // expect this to be invoked on the mock...
replay(testInstance);
testInstance.otherMethod();
verify(testInstance);
}
}
EasyMock doesn't seem to like this. It throws:
java.lang.IllegalArgumentException: Method not found (or private): intfMethod
at org.easymock.internal.MockBuilder.addMockedMethod(MockBuilder.java:78)
at TestAbstractBase.setUp(TestAbstractBase.java:19)
Any ideas? I found a related question but it doesn't really do justice to its title...
Many thanks to #nhaldimann ; I'd overlooked this innocuous statement in the doc, namely that "abstract methods are conveniently mocked by default". So all the above needs is to remove the attempt to explicitly mock the interface method, as in:
testInstance = createMockBuilder(AbstractBase.class).createMock();
While researching this, I came across two other workarounds - although the above is obviously preferable:
Use the stronger addMockedMethod(Method) API, as in:
public void setUp() throws Exception {
Method m = AbstractBase.class.getMethod("intfMethod");
testInstance = createMockBuilder(AbstractBase.class).addMockedMethod(m).createMock();
}
Explicitly expose the intfMethod method in AbstractBase
These two workarounds suggest that my initial issue is a bit of a bug on the EasyMock side of things. But since there's no need to mock that method in the first instance, we'll say this is "user (my) error".
Related
I'm using Mockito in some tests.
I have the following classes:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
I want to mock only the second call (super.save) of ChildService. The first call must call the real method. Is there a way to do that?
If you really don't have a choice for refactoring you can mock/stub everything in the super method call e.g.
class BaseService {
public void validate(){
fail(" I must not be called");
}
public void save(){
//Save method of super will still be called.
validate();
}
}
class ChildService extends BaseService{
public void load(){}
public void save(){
super.save();
load();
}
}
#Test
public void testSave() {
ChildService classToTest = Mockito.spy(new ChildService());
// Prevent/stub logic in super.save()
Mockito.doNothing().when((BaseService)classToTest).validate();
// When
classToTest.save();
// Then
verify(classToTest).load();
}
No, Mockito does not support this.
This might not be the answer you're looking for, but what you're seeing is a symptom of not applying the design principle:
Favor composition over inheritance
If you extract a strategy instead of extending a super class the problem is gone.
If however you are not allowed to change the code, but you must test it anyway, and in this awkward way, there is still hope. With some AOP tools (for example AspectJ) you can weave code into the super class method and avoid its execution entirely (yuck). This doesn't work if you're using proxies, you have to use bytecode modification (either load time weaving or compile time weaving). There are be mocking frameworks that support this type of trick as well, like PowerMock and PowerMockito.
I suggest you go for the refactoring, but if that is not an option you're in for some serious hacking fun.
Consider refactoring the code from ChildService.save() method to different method and test that new method instead of testing ChildService.save(), this way you will avoid unnecessary call to super method.
Example:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
newMethod();
super.save();
}
public void newMethod(){
//some codes
}
}
I found a way to suppress the superclass method using PowerMockito. 3 simple steps need for this
Use PowerMockito.suppress method and MemberMatcher.methodsDeclaredIn method to supress parent class method
Second add Parent class in #PrepareForTest
Run your test class with PowerMock ie add #RunWith(PowerMockRunner.class) above your test class.
#RunWith(PowerMockRunner.class)
#PrepareForTest({BaseService.class})
public class TestChildService(){
#Spy
private ChildService testChildServiceObj = Mockito.spy(new ChildService());
#Test
public void testSave(){
PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(BaseService.class));
//your further test code
testChildServiceObj.save();
}
}
Note: This will work only when the superclass method does not return anything.
Maybe the easiest option if inheritance makes sense is to create a new method (package private??) to call the super (lets call it superFindall), spy the real instance and then mock the superFindAll() method in the way you wanted to mock the parent class one. It's not the perfect solution in terms of coverage and visibility but it should do the job and it's easy to apply.
public Childservice extends BaseService {
public void save(){
//some code
superSave();
}
void superSave(){
super.save();
}
}
create a package protected (assumes test class in same package) method in the sub class that calls the super class method and then call that method in your overridden sub class method. you can then set expectations on this method in your test through the use of the spy pattern. not pretty but certainly better than having to deal with all the expectation setting for the super method in your test
Even if i totally agree with iwein response (
favor composition over inheritance
), i admit there are some times inheritance seems just natural, and i don't feel breaking or refactor it just for the sake of a unit test.
So, my suggestion :
/**
* BaseService is now an asbtract class encapsulating
* some common logic callable by child implementations
*/
abstract class BaseService {
protected void commonSave() {
// Put your common work here
}
abstract void save();
}
public ChildService extends BaseService {
public void save() {
// Put your child specific work here
// ...
this.commonSave();
}
}
And then, in the unit test :
ChildService childSrv = Mockito.mock(ChildService.class, Mockito.CALLS_REAL_METHODS);
Mockito.doAnswer(new Answer<Void>() {
#Override
public Boolean answer(InvocationOnMock invocation)
throws Throwable {
// Put your mocked behavior of BaseService.commonSave() here
return null;
}
}).when(childSrv).commonSave();
childSrv.save();
Mockito.verify(childSrv, Mockito.times(1)).commonSave();
// Put any other assertions to check child specific work is done
You can do this with PowerMockito and replace behavior only of the parent class method with continuing testing the child's class method. Even when the method is returning some value, lets say a string, you can do something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ BaseService.class })
public class TestChildService() {
private BasicService basicServiceObj;
private ChildService testee;
#Before
public void init() throws Exception {
testee = new ChildService();
basicServiceObj = PowerMockito.spy(new BaseService());
PowerMockito.doReturn("Result").when(basicServiceObj, "save", ... optionalArgs);
}
#Test
public void testSave(){
testee.save();
}
}
If you are returning nothing (void) then instead of doReturn you can use doNothing. Add some optionalArgs if the method have some arguments, if not, then skip that part.
The reason is your base class is not public-ed, then Mockito cannot intercept it due to visibility, if you change base class as public, or #Override in sub class (as public), then Mockito can mock it correctly.
public class BaseService{
public boolean foo(){
return true;
}
}
public ChildService extends BaseService{
}
#Test
#Mock ChildService childService;
public void testSave() {
Mockito.when(childService.foo()).thenReturn(false);
// When
assertFalse(childService.foo());
}
There is simple approach that works for most of cases. You can spy your object and stub the method you want to mock.
Here is an example:
MyClass myObjectSpy = Mockito.spy(myObject);
org.mockito.Mockito.doReturn("yourReturnValue").when(mySpyObject).methodToMock(any()..);
So, when you test your object, you can use myObjectSpy and when methodToMock is called, it will overwrite the normal behavior by a mock method.
This code for a method with return. In case you have a void method you can use doNothing instead.
I'm using Mockito in some tests.
I have the following classes:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
I want to mock only the second call (super.save) of ChildService. The first call must call the real method. Is there a way to do that?
If you really don't have a choice for refactoring you can mock/stub everything in the super method call e.g.
class BaseService {
public void validate(){
fail(" I must not be called");
}
public void save(){
//Save method of super will still be called.
validate();
}
}
class ChildService extends BaseService{
public void load(){}
public void save(){
super.save();
load();
}
}
#Test
public void testSave() {
ChildService classToTest = Mockito.spy(new ChildService());
// Prevent/stub logic in super.save()
Mockito.doNothing().when((BaseService)classToTest).validate();
// When
classToTest.save();
// Then
verify(classToTest).load();
}
No, Mockito does not support this.
This might not be the answer you're looking for, but what you're seeing is a symptom of not applying the design principle:
Favor composition over inheritance
If you extract a strategy instead of extending a super class the problem is gone.
If however you are not allowed to change the code, but you must test it anyway, and in this awkward way, there is still hope. With some AOP tools (for example AspectJ) you can weave code into the super class method and avoid its execution entirely (yuck). This doesn't work if you're using proxies, you have to use bytecode modification (either load time weaving or compile time weaving). There are be mocking frameworks that support this type of trick as well, like PowerMock and PowerMockito.
I suggest you go for the refactoring, but if that is not an option you're in for some serious hacking fun.
Consider refactoring the code from ChildService.save() method to different method and test that new method instead of testing ChildService.save(), this way you will avoid unnecessary call to super method.
Example:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
newMethod();
super.save();
}
public void newMethod(){
//some codes
}
}
I found a way to suppress the superclass method using PowerMockito. 3 simple steps need for this
Use PowerMockito.suppress method and MemberMatcher.methodsDeclaredIn method to supress parent class method
Second add Parent class in #PrepareForTest
Run your test class with PowerMock ie add #RunWith(PowerMockRunner.class) above your test class.
#RunWith(PowerMockRunner.class)
#PrepareForTest({BaseService.class})
public class TestChildService(){
#Spy
private ChildService testChildServiceObj = Mockito.spy(new ChildService());
#Test
public void testSave(){
PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(BaseService.class));
//your further test code
testChildServiceObj.save();
}
}
Note: This will work only when the superclass method does not return anything.
Maybe the easiest option if inheritance makes sense is to create a new method (package private??) to call the super (lets call it superFindall), spy the real instance and then mock the superFindAll() method in the way you wanted to mock the parent class one. It's not the perfect solution in terms of coverage and visibility but it should do the job and it's easy to apply.
public Childservice extends BaseService {
public void save(){
//some code
superSave();
}
void superSave(){
super.save();
}
}
create a package protected (assumes test class in same package) method in the sub class that calls the super class method and then call that method in your overridden sub class method. you can then set expectations on this method in your test through the use of the spy pattern. not pretty but certainly better than having to deal with all the expectation setting for the super method in your test
Even if i totally agree with iwein response (
favor composition over inheritance
), i admit there are some times inheritance seems just natural, and i don't feel breaking or refactor it just for the sake of a unit test.
So, my suggestion :
/**
* BaseService is now an asbtract class encapsulating
* some common logic callable by child implementations
*/
abstract class BaseService {
protected void commonSave() {
// Put your common work here
}
abstract void save();
}
public ChildService extends BaseService {
public void save() {
// Put your child specific work here
// ...
this.commonSave();
}
}
And then, in the unit test :
ChildService childSrv = Mockito.mock(ChildService.class, Mockito.CALLS_REAL_METHODS);
Mockito.doAnswer(new Answer<Void>() {
#Override
public Boolean answer(InvocationOnMock invocation)
throws Throwable {
// Put your mocked behavior of BaseService.commonSave() here
return null;
}
}).when(childSrv).commonSave();
childSrv.save();
Mockito.verify(childSrv, Mockito.times(1)).commonSave();
// Put any other assertions to check child specific work is done
You can do this with PowerMockito and replace behavior only of the parent class method with continuing testing the child's class method. Even when the method is returning some value, lets say a string, you can do something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ BaseService.class })
public class TestChildService() {
private BasicService basicServiceObj;
private ChildService testee;
#Before
public void init() throws Exception {
testee = new ChildService();
basicServiceObj = PowerMockito.spy(new BaseService());
PowerMockito.doReturn("Result").when(basicServiceObj, "save", ... optionalArgs);
}
#Test
public void testSave(){
testee.save();
}
}
If you are returning nothing (void) then instead of doReturn you can use doNothing. Add some optionalArgs if the method have some arguments, if not, then skip that part.
The reason is your base class is not public-ed, then Mockito cannot intercept it due to visibility, if you change base class as public, or #Override in sub class (as public), then Mockito can mock it correctly.
public class BaseService{
public boolean foo(){
return true;
}
}
public ChildService extends BaseService{
}
#Test
#Mock ChildService childService;
public void testSave() {
Mockito.when(childService.foo()).thenReturn(false);
// When
assertFalse(childService.foo());
}
There is simple approach that works for most of cases. You can spy your object and stub the method you want to mock.
Here is an example:
MyClass myObjectSpy = Mockito.spy(myObject);
org.mockito.Mockito.doReturn("yourReturnValue").when(mySpyObject).methodToMock(any()..);
So, when you test your object, you can use myObjectSpy and when methodToMock is called, it will overwrite the normal behavior by a mock method.
This code for a method with return. In case you have a void method you can use doNothing instead.
I am facing an issue with Mockito junit testing. I am new to it and am a bit confused with the problem I am facing. Any help on this would be appreciated.
class Activity{
public void firstMethod(){
String str = secondMethod();
}
public String secondMethod(){
String str = null;
/* some Code */
return str;
}
}
Getting exception :
*org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!*
in the below code
class ActivityTest(){
Activity act;
#Before
public void setup(){
act = new Activity();
}
#Test
public void testFirstMethod(){
Mockito.doReturn(Mockito.anyString()).when(act).secondMethod();
act.firstMethod();
verify(act).secondMethod();
}
}
I am aware that activity is not a mock but I am not sure for a way around this as secondMethod() is a method in the same class. I need to write rule for secondMethod() as I have already done its Unit Testing. The definition of secondMethod() consists has external dependencies. Should I be mocking the external dependencies present in secondMethod() and writing rules for them rather than rule for secondMethod()?
I found this post:
Mockito Spy'ing on the object being unit tested
However separating the secondMethod() into a different class does not make sense. My method is related to this class. Creating a different class for testing does not seem right to me. Even mocking the actual class using spy() is not the most correct way as already explained in the post.
I don't think I should be creating a mock of the Activity class as that is the class I am testing. I would really appreciate help and insights into this.
As you noted, act is not a mock, and therefore you cannot record behavior on it. You could use Mockito.spy to, well, spy (or partially mock) the act object so that you only record the behavior of secondMethod and execute the actual code for firstMethod.
Note, however, that matchers can't be used in doReturn calls regardles of how you're mocking or spying your object. A return value must be a concrete object.
class ActivityTest() {
Activity act;
#Before
public void setup(){
act = Mockito.spy(new Activity()); // Here!
}
#Test
public void testFirstMethod(){
Mockito.doReturn("someString").when(act).secondMethod();
act.firstMethod();
verify(act).secondMethod();
}
}
A slightly more elegant syntax allows you to use annotations instead of explicitly calling Mockito.spy, but it's a matter of taste really:
#RunWith(MockitoJUnitRunner.class)
class ActivityTest() {
#Spy
Activity act = new Activity();
#Test
public void testFirstMethod(){
Mockito.doReturn("someString").when(act).secondMethod();
act.firstMethod();
verify(act).secondMethod();
}
}
There is no reason to mock anything in this example. Since there are no dependencies and both methods are public, you can test them directly.
public class ActivityTest() {
private Activity act = new Activity();
#Test
public void testSecondMethod(){
assertEquals("expected-value", act.secondMethod());
}
#Test
public void testFirstMethod() {
act.firstMethod();
// success if no exception occurs
}
}
Since firstMethod does not have any detectable effect on the Act instance, nor on any dependency (since there are none) you can simply call the method and be satisfied if no exception is thrown. One could also reason that such a method should not be tested at all.
I assume the example given is a simplification of a class where calling firstMethod actually does have side effects, who knows...
Here are some hints:
Mock the Activity.
Tweak the behavior of secondMethod with when / then / doReturn
Use doCallRealMethod when firstMethod is invoked.
Hope it helps.
I have this Mockito code:
interface Dao {
public void doSomething();
}
class LegacyClass {
Dao dao;
public String legacyMethod() {
dao.doSomething();
return "Test";
}
}
public class MockitoTest {
public static void main(String[] args) {
Dao dao = mock(Dao.class);
LegacyClass legacyInst = new LegacyClass();
legacyInst.dao = dao;
LegacyClass legacy = spy(legacyInst);
when(legacy.legacyMethod()).thenReturn("Replacement");
}
}
The last when() throws the following exception:
Exception in thread "main" org.mockito.exceptions.base.MockitoException:
'doSomething' is a *void method* and it *cannot* be stubbed with a *return value*!
Voids are usually stubbed with Throwables:
doThrow(exception).when(mock).someVoidMethod();
If the method you are trying to stub is *overloaded* then make sure you are calling the right overloaded version.
at mypkg.MockitoTest.main(MockitoTest.java:28)
However, I am NOT mocking return value for Dao.doSomething, but for LegacyClass.legacyMethod().
Is this the expected behavior? Are there any Mockito docs stating you cannot nest mocks like this?
How can I walk this around?
Spies don't work this way. In your sample code, the real method legacy.legacyMethod() is actually called because it's a spy not a mock (which then calls dao.doSomething()), that's why you are getting this error.
If you want to make a partial mock, you have to write this as :
doReturn("Replacement").when(legacy).legacyMethod();
That way Mockito will know that you want to make a partial mock, so it won't call the real method.
I'm using Mockito in some tests.
I have the following classes:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
I want to mock only the second call (super.save) of ChildService. The first call must call the real method. Is there a way to do that?
If you really don't have a choice for refactoring you can mock/stub everything in the super method call e.g.
class BaseService {
public void validate(){
fail(" I must not be called");
}
public void save(){
//Save method of super will still be called.
validate();
}
}
class ChildService extends BaseService{
public void load(){}
public void save(){
super.save();
load();
}
}
#Test
public void testSave() {
ChildService classToTest = Mockito.spy(new ChildService());
// Prevent/stub logic in super.save()
Mockito.doNothing().when((BaseService)classToTest).validate();
// When
classToTest.save();
// Then
verify(classToTest).load();
}
No, Mockito does not support this.
This might not be the answer you're looking for, but what you're seeing is a symptom of not applying the design principle:
Favor composition over inheritance
If you extract a strategy instead of extending a super class the problem is gone.
If however you are not allowed to change the code, but you must test it anyway, and in this awkward way, there is still hope. With some AOP tools (for example AspectJ) you can weave code into the super class method and avoid its execution entirely (yuck). This doesn't work if you're using proxies, you have to use bytecode modification (either load time weaving or compile time weaving). There are be mocking frameworks that support this type of trick as well, like PowerMock and PowerMockito.
I suggest you go for the refactoring, but if that is not an option you're in for some serious hacking fun.
Consider refactoring the code from ChildService.save() method to different method and test that new method instead of testing ChildService.save(), this way you will avoid unnecessary call to super method.
Example:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
newMethod();
super.save();
}
public void newMethod(){
//some codes
}
}
I found a way to suppress the superclass method using PowerMockito. 3 simple steps need for this
Use PowerMockito.suppress method and MemberMatcher.methodsDeclaredIn method to supress parent class method
Second add Parent class in #PrepareForTest
Run your test class with PowerMock ie add #RunWith(PowerMockRunner.class) above your test class.
#RunWith(PowerMockRunner.class)
#PrepareForTest({BaseService.class})
public class TestChildService(){
#Spy
private ChildService testChildServiceObj = Mockito.spy(new ChildService());
#Test
public void testSave(){
PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(BaseService.class));
//your further test code
testChildServiceObj.save();
}
}
Note: This will work only when the superclass method does not return anything.
Maybe the easiest option if inheritance makes sense is to create a new method (package private??) to call the super (lets call it superFindall), spy the real instance and then mock the superFindAll() method in the way you wanted to mock the parent class one. It's not the perfect solution in terms of coverage and visibility but it should do the job and it's easy to apply.
public Childservice extends BaseService {
public void save(){
//some code
superSave();
}
void superSave(){
super.save();
}
}
create a package protected (assumes test class in same package) method in the sub class that calls the super class method and then call that method in your overridden sub class method. you can then set expectations on this method in your test through the use of the spy pattern. not pretty but certainly better than having to deal with all the expectation setting for the super method in your test
Even if i totally agree with iwein response (
favor composition over inheritance
), i admit there are some times inheritance seems just natural, and i don't feel breaking or refactor it just for the sake of a unit test.
So, my suggestion :
/**
* BaseService is now an asbtract class encapsulating
* some common logic callable by child implementations
*/
abstract class BaseService {
protected void commonSave() {
// Put your common work here
}
abstract void save();
}
public ChildService extends BaseService {
public void save() {
// Put your child specific work here
// ...
this.commonSave();
}
}
And then, in the unit test :
ChildService childSrv = Mockito.mock(ChildService.class, Mockito.CALLS_REAL_METHODS);
Mockito.doAnswer(new Answer<Void>() {
#Override
public Boolean answer(InvocationOnMock invocation)
throws Throwable {
// Put your mocked behavior of BaseService.commonSave() here
return null;
}
}).when(childSrv).commonSave();
childSrv.save();
Mockito.verify(childSrv, Mockito.times(1)).commonSave();
// Put any other assertions to check child specific work is done
You can do this with PowerMockito and replace behavior only of the parent class method with continuing testing the child's class method. Even when the method is returning some value, lets say a string, you can do something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ BaseService.class })
public class TestChildService() {
private BasicService basicServiceObj;
private ChildService testee;
#Before
public void init() throws Exception {
testee = new ChildService();
basicServiceObj = PowerMockito.spy(new BaseService());
PowerMockito.doReturn("Result").when(basicServiceObj, "save", ... optionalArgs);
}
#Test
public void testSave(){
testee.save();
}
}
If you are returning nothing (void) then instead of doReturn you can use doNothing. Add some optionalArgs if the method have some arguments, if not, then skip that part.
The reason is your base class is not public-ed, then Mockito cannot intercept it due to visibility, if you change base class as public, or #Override in sub class (as public), then Mockito can mock it correctly.
public class BaseService{
public boolean foo(){
return true;
}
}
public ChildService extends BaseService{
}
#Test
#Mock ChildService childService;
public void testSave() {
Mockito.when(childService.foo()).thenReturn(false);
// When
assertFalse(childService.foo());
}
There is simple approach that works for most of cases. You can spy your object and stub the method you want to mock.
Here is an example:
MyClass myObjectSpy = Mockito.spy(myObject);
org.mockito.Mockito.doReturn("yourReturnValue").when(mySpyObject).methodToMock(any()..);
So, when you test your object, you can use myObjectSpy and when methodToMock is called, it will overwrite the normal behavior by a mock method.
This code for a method with return. In case you have a void method you can use doNothing instead.