Mocking - zero interactions - java

I have written a test to verify that a public method in my class is called. My test is failing as follows. Can anyone tell me why this happening?
Wanted but not invoked: `mockMyClass.runThis();
Actually, there were zero interactions with this mock.
class MyClass{
public void myMethod(){
runThis("hello");
}
}
public void runThis(String str){
return;
}
Test class
#Mock
MyClass mockMyClass;
MyClass myClass = new MyClass();
#Test
public void test(){
myClass.myMethod();
verify(mockMyClass).runThis(anyString());
}

You're not invoking against your mock, but rather the real class. You need to generate a mock, and then invoke on that mock. Try something like:
MyClass mock = mock(MyClass.class); // I'm using the methods rather than annotation here
mock.myMethod();
and assert on that. I'm not quite sure in the above where runThis() is, though. If it's on a contained class, then that's the thing to need to mock. If it's on the same class, then you can't use a mock per se, since the mock substitutes all functionality, and perhaps the Mockito spy() mechanism would be of use here. Section 13 of the doc advises more on this.

Related

Mock a static method that's inside a static method

I have a static method (foo) that calls another static method (bar). I would like to mock the response of bar in my test. Is this possible with PowerMockito or another tool? the only results I can find are for mocking statics inside of non-static methods.
public class SomeClass {
static List<String> foo() {
...
int barResult = bar();
...
}
static int bar() {
// make a database call
return DAO.getDao().runQuery();
}
}
And my test will call it like:
#RunWith(PowerMockRunner.class)
public class SomeClassTest {
#PrepareForTest(SomeClass.class)
#Test
public void fooTest() {
List<String> actualResult = SomeClass.foo();
assertTrue(...);
}
}
Am I going to have to mock the internals of bar? So mock the DAO?
You can't do that.
Only PowerMock allows you to mock static methods. But that works by "erasing" all static things within that class that gets "prepared" for testing by PowerMock.
If you were talking about ordinary methods, you could be going for Mockito spies, as those allow for partial mockings.
And just for the record: simply avoid using static, as using it leads to "hard to test" code.
In other words: instead of using the big ugly powermock hammer to "fix" your design problems... Consider fixing your broken design instead and thereby avoiding the need for PowerMock altogether!
And for the record: yes, you could solve your problem by mocking that static call on the DAO class (then you can control what bar() does indirectly. But again: that would just mean to put the "I tested it" label on code that should be reworked instead.
You can do:
#RunWith(PowerMockRunner.class)
#PrepareForTest({SomeClass.class, DAO.class})
public class SomeClassTest {
#Test
public void fooTest() {
PowerMockito.mockStatic(DAO.class);
Mockito.when(DAO.getDao().runQuery()).return(..);
List<String> actualResult = SomeClass.foo();
assertTrue(...);
}
}

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"));
}

mockito return sequence of objects on spy method

I know you can set several different objects to be be returned on a mock. Ex.
when(someObject.getObject()).thenReturn(object1,object2,object3);
Can you do the same thing with a spied object somehow? I tried the above on a spy with no luck. I read in the docs to use doReturn() on a spy like below
doReturn("foo").when(spy).get(0);
But deReturn() only accepts one parameter. I'd like to return different objects in a specific order on a spy. Is this possible?
I have a class like the following and i'm trying to test it. I want to test myClass, not anotherClass
public class myClass{
//class code that needs several instances of `anotherClass`
public anotherClass getObject(){
return new anotherClass();
}
}
You can chain doReturn() calls before when(), so this works (mockito 1.9.5):
private static class Meh
{
public String meh() { return "meh"; }
}
#Test
public void testMeh()
{
final Meh meh = spy(new Meh());
doReturn("foo").doReturn("bar").doCallRealMethod().when(meh).meh();
assertEquals("foo", meh.meh());
assertEquals("bar", meh.meh());
assertEquals("meh", meh.meh());
}
Also, I didn't know you could do when(x.y()).thenReturn(z1,z2), when I have to do this I use chained .thenReturn() calls as well:
when(x.y()).thenReturn(z1).thenThrow().thenReturn(z2)

Get method invocated inside a method in Java

I want to make a JUnit test to assure that some classes don't use a specific set of methods (from another classes). Example
class MyClass
{
void myMethod()
{
otherClass.otherClassStaticMethod();
}
}
class myTest
{
void test()
{
assertFalse(CalledMethods.getMethodsCalledBy("myClass.myMethod").Contains("otherClass.otherClassStaticMethod"));
}
}
In this test I want to assure that myMethod doesn't invocate otherClassStaticMethod. How can I find what methods are being called inside a method in compile time (ignore methods called using reflection)? I thought about a .java parser, do you recommend any?
you can mock "otherClass" and verify that the method isn't invoked. E.g. using Mockito you can even specify in which order what methods are supposed to be invoked (under the condition their instances are mocks) and specify which methods are not allowed to be invoked
as coding.mof said, to mock static methods you should use PowerMock/PowerMockito:
example:
PowerMockito.mockStatic(OtherClass.class);
PowerMockito.verifyStatic(never());
OtherClass.otherClassStaticMethod();
It sounds like you should be using a mock library and let that handle it all for you. I'd recommend JMock as my library of choice. If you're using instance methods then this would be perfect for you - if, as your example shows, it's static methods then PowerMock may work*1.
With JMock, you'd have something like:
public class MyClass {
public MyClass(Dependency dependency) {
this.dependency = dependency;
}
void myMethod() {
dependency.someMethod();
}
}
#RunWith(JMock.class)
public class MyTest {
private Mockery context = new Mockery();
#Test
public void doesNotCallSomeMethod() {
Dependency dependency = context.mock(Dependency.class);
MyClass obj = new MyClass(dependency);
obj.myMethod(); <--- this will fail fast
}
}
When you call obj.myMethod, JMock will instantly report that you never said dependency should have any methods called. It will also tell you what method you DID call and what parameters you passed in if any
*1 I don't use PowerMock as I steer away from static methods unless they are pure functions

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