How to write unit test using mock object? - java

The more I read mock example, the more I get confused...
I have classA method eat() that calls FatDude class eatThemAll()
public class classA {
FatDude dude = new FatDude();
public String eat() {
String result = dude.eatThemAll();
}
}
public class FatDude {
public String eatThemAll() {
return "never full";
}
}
Now I want to test classA eat() method by mocking FatDude class.
public class MockFatDude extends FatDude {
//override
public String eatThemAll() {
return "very full";
}
}
------------- test --------------
public class DoTest {
public void runTest() {
classA cl = new ClassA();
String out = cl.eat();
assertEqual(out, "very full");
}
}
This DoTest runTest() won't use MockFatDude class of course. One way I can think is to change the code to pass FatDude to eat() method of ClassA like:
public class classA {
public String eat(FatDude dude) {
String result = dude.eatThemAll();
}
}
Then change my test method to:
public class DoTest {
public void runTest() {
classA cl = new ClassA();
String out = cl.eat(new MockFatDude());
assertEqual(out, "very full");
}
}
But as you can see, I had to change the source code to meet my need.
Is this the right way to do? What if I am not allowed to change my source code?
I know if I apply TDD concept, it is OK to change source code but I would like to hear
some opinion or advice if what I have shown above is right way to do.

Mocking and the Dependency Inversion Principle (DIP) go hand in hand, and in most languages, Mocks work best by decoupling classes by means of interfaces.
In your instance, this will work without you needing to change code: (Edit : I mean, in future, if you design your app this way, you won't need to change code to mock dependencies :))
Abstract an interface IDude
Concrete classes FatDude (and MockFatDude) should implement IDude interface
provide a mechanism for an IDude instance to be 'set' or injected into classA - Dependency Injection (constructor or get / sets); or Service Locator pattern work best (to replace a concrete classfactory)
Also note that many mocking frameworks actually allow you to build up the Mock concrete class 'on the fly' (see MoQ et al), so you can create the functionality of MockFatDude directly in your unit test.

Yes. You've stumbled on some good design directly because of your unit test. If you look more closely, you'll see that you removed the coupling between classA and FatDude. Now FatDude can be an interface for behavior that gets passed in when needed. ClassA doesn't need to know what kind of FatDude it's getting, or how to construct a FatDude (with cheeseburgers?).
Your solution is exactly what I would have done. There's nothing wrong with changing your code to accomodate TDD, as long as you understand the reasons and the benfits/drawbacks to making such changes.

Related

Mockito how to mock a private method [duplicate]

public class A {
public void method(boolean b){
if (b == true)
method1();
else
method2();
}
private void method1() {}
private void method2() {}
}
public class TestA {
#Test
public void testMethod() {
A a = mock(A.class);
a.method(true);
//how to test like verify(a).method1();
}
}
How to test private method is called or not, and how to test private method using mockito?
Not possible through mockito. From their wiki
Why Mockito doesn't mock private methods?
Firstly, we are not dogmatic about mocking private methods. We just
don't care about private methods because from the standpoint of
testing private methods don't exist. Here are a couple of reasons
Mockito doesn't mock private methods:
It requires hacking of classloaders that is never bullet proof and it
changes the api (you must use custom test runner, annotate the class,
etc.).
It is very easy to work around - just change the visibility of method
from private to package-protected (or protected).
It requires me to spend time implementing & maintaining it. And it
does not make sense given point #2 and a fact that it is already
implemented in different tool (powermock).
Finally... Mocking private methods is a hint that there is something
wrong with OO understanding. In OO you want objects (or roles) to
collaborate, not methods. Forget about pascal & procedural code. Think
in objects.
You can't do that with Mockito but you can use Powermock to extend Mockito and mock private methods. Powermock supports Mockito. Here's an example.
Here is a small example how to do it with powermock
public class Hello {
private Hello obj;
private Integer method1(Long id) {
return id + 10;
}
}
To test method1 use code:
Hello testObj = new Hello();
Integer result = Whitebox.invokeMethod(testObj, "method1", new Long(10L));
To set private object obj use this:
Hello testObj = new Hello();
Hello newObject = new Hello();
Whitebox.setInternalState(testObj, "obj", newObject);
While Mockito doesn't provide that capability, you can achieve the same result using Mockito + the JUnit ReflectionUtils class or the Spring ReflectionTestUtils class. Please see an example below taken from here explaining how to invoke a private method:
ReflectionTestUtils.invokeMethod(student, "saveOrUpdate", "From Unit test");
Complete examples with ReflectionTestUtils and Mockito can be found in the book Mockito for Spring.
Official documentation Spring Testing
By using reflection, private methods can be called from test classes.
In this case,
//test method will be like this ...
public class TestA {
#Test
public void testMethod() {
A a= new A();
Method privateMethod = A.class.getDeclaredMethod("method1", null);
privateMethod.setAccessible(true);
// invoke the private method for test
privateMethod.invoke(A, null);
}
}
If the private method calls any other private method, then we need to spy the object and stub the another method.The test class will be like ...
//test method will be like this ...
public class TestA {
#Test
public void testMethod() {
A a= new A();
A spyA = spy(a);
Method privateMethod = A.class.getDeclaredMethod("method1", null);
privateMethod.setAccessible(true);
doReturn("Test").when(spyA, "method2"); // if private method2 is returning string data
// invoke the private method for test
privateMethod.invoke(spyA , null);
}
}
**The approach is to combine reflection and spying the object.
**method1 and **method2 are private methods and method1 calls method2.
Think about this in terms of behaviour, not in terms of what methods there are. The method called method has a particular behaviour if b is true. It has different behaviour if b is false. This means you should write two different tests for method; one for each case. So instead of having three method-oriented tests (one for method, one for method1, one for method2, you have two behaviour-oriented tests.
Related to this (I suggested this in another SO thread recently, and got called a four-letter word as a result, so feel free to take this with a grain of salt); I find it helpful to choose test names that reflect the behaviour that I'm testing, rather than the name of the method. So don't call your tests testMethod(), testMethod1(), testMethod2() and so forth. I like names like calculatedPriceIsBasePricePlusTax() or taxIsExcludedWhenExcludeIsTrue() that indicate what behaviour I'm testing; then within each test method, test only the indicated behaviour. Most such behaviours will involve just one call to a public method, but may involve many calls to private methods.
Hope this helps.
I was able to test a private method inside using mockito using reflection.
Here is the example, tried to name it such that it makes sense
//Service containing the mock method is injected with mockObjects
#InjectMocks
private ServiceContainingPrivateMethod serviceContainingPrivateMethod;
//Using reflection to change accessibility of the private method
Class<?>[] params = new Class<?>[]{PrivateMethodParameterOne.class, PrivateMethodParameterTwo.class};
Method m = serviceContainingPrivateMethod .getClass().getDeclaredMethod("privateMethod", params);
//making private method accessible
m.setAccessible(true);
assertNotNull(m.invoke(serviceContainingPrivateMethod, privateMethodParameterOne, privateMethodParameterTwo).equals(null));
You're not suppose to test private methods. Only non-private methods needs to be tested as these should call the private methods anyway. If you "want" to test private methods, it may indicate that you need to rethink your design:
Am I using proper dependency injection?
Do I possibly needs to move the private methods into a separate class and rather test that?
Must these methods be private? ...can't they be default or protected rather?
In the above instance, the two methods that are called "randomly" may actually need to be placed in a class of their own, tested and then injected into the class above.
There is actually a way to test methods from a private member with Mockito. Let's say you have a class like this:
public class A {
private SomeOtherClass someOtherClass;
A() {
someOtherClass = new SomeOtherClass();
}
public void method(boolean b){
if (b == true)
someOtherClass.method1();
else
someOtherClass.method2();
}
}
public class SomeOtherClass {
public void method1() {}
public void method2() {}
}
If you want to test a.method will invoke a method from SomeOtherClass, you can write something like below.
#Test
public void testPrivateMemberMethodCalled() {
A a = new A();
SomeOtherClass someOtherClass = Mockito.spy(new SomeOtherClass());
ReflectionTestUtils.setField( a, "someOtherClass", someOtherClass);
a.method( true );
Mockito.verify( someOtherClass, Mockito.times( 1 ) ).method1();
}
ReflectionTestUtils.setField(); will stub the private member with something you can spy on.
I don't really understand your need to test the private method. The root problem is that your public method has void as return type, and hence you are not able to test your public method. Hence you are forced to test your private method. Is my guess correct??
A few possible solutions (AFAIK):
Mocking your private methods, but still you won't be "actually" testing your methods.
Verify the state of object used in the method. MOSTLY methods either do some processing of the input values and return an output, or change the state of the objects. Testing the objects for the desired state can also be employed.
public class A{
SomeClass classObj = null;
public void publicMethod(){
privateMethod();
}
private void privateMethod(){
classObj = new SomeClass();
}
}
[Here you can test for the private method, by checking the state change of the classObj from null to not null.]
Refactor your code a little (Hope this is not a legacy code). My funda of writing a method is that, one should always return something (a int/ a boolean). The returned value MAY or MAY NOT be used by the implementation, but it will SURELY BE used by the test
code.
public class A
{
public int method(boolean b)
{
int nReturn = 0;
if (b == true)
nReturn = method1();
else
nReturn = method2();
}
private int method1() {}
private int method2() {}
}
Put your test in the same package, but a different source folder (src/main/java vs. src/test/java) and make those methods package-private. Imo testability is more important than privacy.
In cases where the private method is not void and the return value is used as a parameter to an external dependency's method, you can mock the dependency and use an ArgumentCaptor to capture the return value.
For example:
ArgumentCaptor<ByteArrayOutputStream> csvOutputCaptor = ArgumentCaptor.forClass(ByteArrayOutputStream.class);
//Do your thing..
verify(this.awsService).uploadFile(csvOutputCaptor.capture());
....
assertEquals(csvOutputCaptor.getValue().toString(), "blabla");
Building on #aravind-yarram's answer: Not possible through mockito. From their wiki
So what's the OO way of testing private methods? Private methods with complex logic might be a sign that your class is violating the principle of single responsibility and that some of the logic should be moved to a new class.
Indeed, by extracting those private methods to public methods of more granular classes, you can unit test them without breaking the encapsulation of your original class.

How can i mock an inherited method of the class i am testing

I have code similar to this
class Util{
public String transform(String str);
//lots of logic including ajax calls
return("Modified"+str);
}
public caseChange(String str){
//lots of logic including ajax calls
return str.toUpperCase()
}
class TextParser extends Util{
public String parse(str)
//lots of logic to modify str
str = caseChange(str);
//some more logic to modify str
return transform(str);
}
Is there anyway to mock the caseChange and transform methods to return some mocked data and prevent a call to the superclass when i call
String result = new TextParser().parse("hello")
in the unit test class to assert result.
The transform and changeCase are over simplified in my example. In reality they perform ajax calls and there is a ton of other logic. I want to mock them out so that can unit test just this part an then unit test the super methods later
You may need to create another subclass like
class TextParserForTest extends TextParser {
#Override
public String parse(String str) {
super.parse(str);
}
#Override
public String caseChange(String str) {
return "whatever";
}
}
edit : use mockito to this :
import static org.mockito.Mockito.*;
import org.junit.Test;
#Test
public void test() {
TextParser tp = mock(TextParser.class);
// all the methods that you want to test
when(tp.parse(any())).thenCallRealMethod();
when...
// all the methods that you want to mock
when(tp.caseChange(any()).thenReturn("whatever");
when...
}
In your given example: you simply don't do that. Your methods are only working on your inputs; so it should absolutely not matter where those methods are implemented.
In other words: it seems most appropriate for you to focus on contract checking tests only. Like:
#Test
public testWhatever() {
assertThat(new TextParser.parse("hello"), is("expected output"));
}
Yes, you can probably mock such things using Mockito/Powermock; but you shouldn't! You see, your production code is directly calling those methods; so you want to test that calling parse gives you expected results (while using all the code that will also run in a production setup!)
Edit: given your comment about that methods being "complicated". Then I suggest: do not use inheritance here. You should not make class B a subclass of A just to have easy access to some methods. In other words: inheritance is about modeling an IS-A relation. So, a TextParser is a Util? Doesn't sound very convincing.
Thus: you better turn to composition here. Your TextParser should use a Util object. And that one can be provided via dependency injection; and your need to mock with inherited methods vanishes completely!
You can use the spy functionality of Mockito. The spy calls real methods unless they are stubbed.
#Test
public void testParse() {
TextParser textParser = Mockito.spy(new TextParser());
when(textParser.caseChange(Matchers.anyString())).thenReturn("mocked");
Assert.assertEquals("Modifiedmocked", textParser.parse("hello"));
}

Unit testing without dependency injection

Code from Spring in Action :
public class DamselRescuingKnight implements Knight {
private RescueDamselQuest quest;
public DamselRescuingKnight() {
this.quest = new RescueDamselQuest();
}
public void embarkOnQuest() {
quest.embark();
}
}
public class BraveKnight implements Knight {
private Quest quest;
public BraveKnight(Quest quest) {
this.quest = quest;
}
public void embarkOnQuest() {
quest.embark();
}
}
public class BraveKnightTest {
#Test
public void knightShouldEmbarkOnQuest() {
Quest mockQuest = mock(Quest.class);
BraveKnight knight = new BraveKnight(mockQuest);
knight.embarkOnQuest();
verify(mockQuest, times(1)).embark();
}
}
I understand the use of dependency injection, which allows us to switch implementation without modifying the depending code.
The book says "terribly difficult to write a unit test ...".
However, I am not able to understand how it will be very difficult for unit-testing without dependency injection! My intuition refuses to co-operate !
Can you start writing junit/unit testing for the class "DamselRescuingKnight" and for any other better example class (without DI), to make me realize the point/stage at which DI makes unit testing easier ?
The difficulty in your above example comes when you try to test DamselRescuingKnight. Assume, you want to test that one (see below)
public class DamselRescuingKnight implements Knight {
private RescueDamselQuest quest;
public DamselRescuingKnight() {
this.quest = new RescueDamselQuest();
}
public void embarkOnQuest() {
quest.embark();
}
}
public class DamselRescuingKnightTest {
#Test
public void knightShouldEmbarkOnQuest() {
DamselRescuingKnight knight = new DamselRescuingKnight ();
knight.embarkOnQuest();
// now what?
}
}
how can you be sure that knight.embarkOnQuest() does actually do anything? The answer is that you can't because you can't access the quest instance it uses internally.
Now in order to be able to test such a class, you would add a getQuest() method to the Knight, and then also add a isEmbarked() method to Quest.
It is also quite fair to say, that this example is very simple, because the knight only calls the quest without parameters, and nothing else. If knight would interact with a quest and also get some weaponary from a Blacksmith, then you would also somehow need to allow access for that. You could probably do all the boilerplate to get that done. But then assume, you're passing parameters to blacksmith - how do you ensure that the passed parameters were correct? Or how do you ensure that the knight gets his/her weapon before going to the quest?
This is where dependency injection comes to the rescue. you can just create mocks (either by using a mock framework, or by implementing your own mocks) so that you can verify that your knight does the expected things.
The problem is of course the quest variable. You want to somehow check that the embark() method is invoked. Without being able to replace it with a mocked instance, this is very hard.
If the variable were protected instead of private, the test case could overwrite it by virtue of living in the same package.
You can also use Aspect-Oriented Programming to replace the variable.
But the easiest is if the code is written with dependency injection from the get-go.
You ask to see how AOP can be used. The following is an example of an AspectJ pointcut that you can use in a unit test to replace the RescueDamselQuest instance with a mocked one called MockRescueDamselQuest (apologies if I don't get the syntax exactly right, it has been a while since I used AspectJ):
aspect MockRescueDamselQuestInstantiations {
RescueDamselQuest around (): call(RescueDamselQuest.new()) {
return new MockRescueDamselQuest();
}
}
This will catch any instantiations of RescueDamselQuest (i.e. calls to new RescueDamselQuest()) and return a MockRescueDamselQuest object instead.
Given how much more wiring this requirest, I'd strongly suggest using dependency injection instead!
This perplexed me as well when I was reading this in Spring in Action. After reading above answers I wanted to add that when DI is not used then Junit method need to call method of object which is private (which is in accessible) and this object Quest is created in constructor of DamselRescuingKnight so test case for embarkQuest() can't be written. On contrary when using DI then you are externalizing object creation and Junit method can create that object so it will be accessible to it then can test emabarkQuest() which eventually need to test quest method

Testing Private method using mockito

public class A {
public void method(boolean b){
if (b == true)
method1();
else
method2();
}
private void method1() {}
private void method2() {}
}
public class TestA {
#Test
public void testMethod() {
A a = mock(A.class);
a.method(true);
//how to test like verify(a).method1();
}
}
How to test private method is called or not, and how to test private method using mockito?
Not possible through mockito. From their wiki
Why Mockito doesn't mock private methods?
Firstly, we are not dogmatic about mocking private methods. We just
don't care about private methods because from the standpoint of
testing private methods don't exist. Here are a couple of reasons
Mockito doesn't mock private methods:
It requires hacking of classloaders that is never bullet proof and it
changes the api (you must use custom test runner, annotate the class,
etc.).
It is very easy to work around - just change the visibility of method
from private to package-protected (or protected).
It requires me to spend time implementing & maintaining it. And it
does not make sense given point #2 and a fact that it is already
implemented in different tool (powermock).
Finally... Mocking private methods is a hint that there is something
wrong with OO understanding. In OO you want objects (or roles) to
collaborate, not methods. Forget about pascal & procedural code. Think
in objects.
You can't do that with Mockito but you can use Powermock to extend Mockito and mock private methods. Powermock supports Mockito. Here's an example.
Here is a small example how to do it with powermock
public class Hello {
private Hello obj;
private Integer method1(Long id) {
return id + 10;
}
}
To test method1 use code:
Hello testObj = new Hello();
Integer result = Whitebox.invokeMethod(testObj, "method1", new Long(10L));
To set private object obj use this:
Hello testObj = new Hello();
Hello newObject = new Hello();
Whitebox.setInternalState(testObj, "obj", newObject);
While Mockito doesn't provide that capability, you can achieve the same result using Mockito + the JUnit ReflectionUtils class or the Spring ReflectionTestUtils class. Please see an example below taken from here explaining how to invoke a private method:
ReflectionTestUtils.invokeMethod(student, "saveOrUpdate", "From Unit test");
Complete examples with ReflectionTestUtils and Mockito can be found in the book Mockito for Spring.
Official documentation Spring Testing
By using reflection, private methods can be called from test classes.
In this case,
//test method will be like this ...
public class TestA {
#Test
public void testMethod() {
A a= new A();
Method privateMethod = A.class.getDeclaredMethod("method1", null);
privateMethod.setAccessible(true);
// invoke the private method for test
privateMethod.invoke(A, null);
}
}
If the private method calls any other private method, then we need to spy the object and stub the another method.The test class will be like ...
//test method will be like this ...
public class TestA {
#Test
public void testMethod() {
A a= new A();
A spyA = spy(a);
Method privateMethod = A.class.getDeclaredMethod("method1", null);
privateMethod.setAccessible(true);
doReturn("Test").when(spyA, "method2"); // if private method2 is returning string data
// invoke the private method for test
privateMethod.invoke(spyA , null);
}
}
**The approach is to combine reflection and spying the object.
**method1 and **method2 are private methods and method1 calls method2.
Think about this in terms of behaviour, not in terms of what methods there are. The method called method has a particular behaviour if b is true. It has different behaviour if b is false. This means you should write two different tests for method; one for each case. So instead of having three method-oriented tests (one for method, one for method1, one for method2, you have two behaviour-oriented tests.
Related to this (I suggested this in another SO thread recently, and got called a four-letter word as a result, so feel free to take this with a grain of salt); I find it helpful to choose test names that reflect the behaviour that I'm testing, rather than the name of the method. So don't call your tests testMethod(), testMethod1(), testMethod2() and so forth. I like names like calculatedPriceIsBasePricePlusTax() or taxIsExcludedWhenExcludeIsTrue() that indicate what behaviour I'm testing; then within each test method, test only the indicated behaviour. Most such behaviours will involve just one call to a public method, but may involve many calls to private methods.
Hope this helps.
I was able to test a private method inside using mockito using reflection.
Here is the example, tried to name it such that it makes sense
//Service containing the mock method is injected with mockObjects
#InjectMocks
private ServiceContainingPrivateMethod serviceContainingPrivateMethod;
//Using reflection to change accessibility of the private method
Class<?>[] params = new Class<?>[]{PrivateMethodParameterOne.class, PrivateMethodParameterTwo.class};
Method m = serviceContainingPrivateMethod .getClass().getDeclaredMethod("privateMethod", params);
//making private method accessible
m.setAccessible(true);
assertNotNull(m.invoke(serviceContainingPrivateMethod, privateMethodParameterOne, privateMethodParameterTwo).equals(null));
You're not suppose to test private methods. Only non-private methods needs to be tested as these should call the private methods anyway. If you "want" to test private methods, it may indicate that you need to rethink your design:
Am I using proper dependency injection?
Do I possibly needs to move the private methods into a separate class and rather test that?
Must these methods be private? ...can't they be default or protected rather?
In the above instance, the two methods that are called "randomly" may actually need to be placed in a class of their own, tested and then injected into the class above.
There is actually a way to test methods from a private member with Mockito. Let's say you have a class like this:
public class A {
private SomeOtherClass someOtherClass;
A() {
someOtherClass = new SomeOtherClass();
}
public void method(boolean b){
if (b == true)
someOtherClass.method1();
else
someOtherClass.method2();
}
}
public class SomeOtherClass {
public void method1() {}
public void method2() {}
}
If you want to test a.method will invoke a method from SomeOtherClass, you can write something like below.
#Test
public void testPrivateMemberMethodCalled() {
A a = new A();
SomeOtherClass someOtherClass = Mockito.spy(new SomeOtherClass());
ReflectionTestUtils.setField( a, "someOtherClass", someOtherClass);
a.method( true );
Mockito.verify( someOtherClass, Mockito.times( 1 ) ).method1();
}
ReflectionTestUtils.setField(); will stub the private member with something you can spy on.
I don't really understand your need to test the private method. The root problem is that your public method has void as return type, and hence you are not able to test your public method. Hence you are forced to test your private method. Is my guess correct??
A few possible solutions (AFAIK):
Mocking your private methods, but still you won't be "actually" testing your methods.
Verify the state of object used in the method. MOSTLY methods either do some processing of the input values and return an output, or change the state of the objects. Testing the objects for the desired state can also be employed.
public class A{
SomeClass classObj = null;
public void publicMethod(){
privateMethod();
}
private void privateMethod(){
classObj = new SomeClass();
}
}
[Here you can test for the private method, by checking the state change of the classObj from null to not null.]
Refactor your code a little (Hope this is not a legacy code). My funda of writing a method is that, one should always return something (a int/ a boolean). The returned value MAY or MAY NOT be used by the implementation, but it will SURELY BE used by the test
code.
public class A
{
public int method(boolean b)
{
int nReturn = 0;
if (b == true)
nReturn = method1();
else
nReturn = method2();
}
private int method1() {}
private int method2() {}
}
Put your test in the same package, but a different source folder (src/main/java vs. src/test/java) and make those methods package-private. Imo testability is more important than privacy.
In cases where the private method is not void and the return value is used as a parameter to an external dependency's method, you can mock the dependency and use an ArgumentCaptor to capture the return value.
For example:
ArgumentCaptor<ByteArrayOutputStream> csvOutputCaptor = ArgumentCaptor.forClass(ByteArrayOutputStream.class);
//Do your thing..
verify(this.awsService).uploadFile(csvOutputCaptor.capture());
....
assertEquals(csvOutputCaptor.getValue().toString(), "blabla");
Building on #aravind-yarram's answer: Not possible through mockito. From their wiki
So what's the OO way of testing private methods? Private methods with complex logic might be a sign that your class is violating the principle of single responsibility and that some of the logic should be moved to a new class.
Indeed, by extracting those private methods to public methods of more granular classes, you can unit test them without breaking the encapsulation of your original class.

Can I mock a super class method call?

Sometimes, you want to test a class method and you want to do an expectation on a call of a super class method. I did not found a way to do this expectation in java using easymock or jmock (and I think it is not possible).
There is a (relative) clean solution, to create a delegate with the super class method logic and then set expectations on it, but I don't know why and when use that solution ¿any ideas/examples?
Thanks
Well, you can if you want to. I don't know if you are familiar with JMockit, go check it out. The current version is 0.999.17 In the mean time, let's take a look at it...
Assume the following class hierarchy:
public class Bar {
public void bar() {
System.out.println("Bar#bar()");
}
}
public class Foo extends Bar {
public void bar() {
super.bar();
System.out.println("Foo#bar()");
}
}
Then, using JMockit in your FooTest.java you can validate that you're actually making a call to Bar from Foo.
#MockClass(realClass = Bar.class)
public static class MockBar {
private boolean barCalled = false;
#Mock
public void bar() {
this.barCalled = true;
System.out.println("mocked bar");
}
}
#Test
public void barShouldCallSuperBar() {
MockBar mockBar = new MockBar();
Mockit.setUpMock(Bar.class, mockBar);
Foo foo = new Foo();
foo.bar();
Assert.assertTrue(mockBar.barCalled);
Mockit.tearDownMocks();
}
Expanding on #Cem Catikkas answer, using JMockit 1.22:
#Test
public void barShouldCallSuperBar() {
new MockUp<Bar>() {
#Mock
public void bar() {
barCalled = true;
System.out.println("mocked bar");
}
};
Foo foo = new Foo();
foo.bar();
Assert.assertTrue(mockBar.barCalled);
}
No need for the static class annotated with #MockClass, it is replaced by the MockUp class.
I don't think I'd mock out a super call - it feels to me like the behaviour there is part of the behaviour of the class itself, rather than the behaviour of a dependency. Mocking always feels like it should be to do with dependencies more than anything else.
Do you have a good example of the kind of call you want to mock out? If you want to mock out a call like this, would it be worth considering composition instead of inheritance?
There are several tests that do just that (ie specify an expected invocation on a super-class method) using the JMockit Expectations API, in the Animated Transitions sample test suite. For example, the FadeInTest test case.
No, there is no way of mocking super class methods with jMock.
However there is a quick-and-dirty solution to your problem. Suppose you have class A and class B extends A. You want to mock method A.a() on B. You can introduce class C extends B in your test code and override the method C.a() (just call super, or return null, id does not matter). After that mock C and use the mock everywhere, where you'd use B.
intercepting a super call is much too fine-grained. Don't overdo the isolation.

Categories