Is it possible to test static functions by easyMock - java

I want to check if it returns with same value by using EasyMock's andReturn method. Unfortunately, I come across with "java.lang.IllegalStateException: missing behavior definition for the preceding method call:" when I use EasyMock. I guess it is not possible to test by EasyMock when I try expect method. You will understand question better in the code.
Regards
Alper
Menu menu = EasyMock.createMock(Menu.class)
menu.setName("name");
EasyMock.expect(XmlParseUtility.createLinesToParse(menu).toString()).andReturn(angularLines.toString());
Error Message :
java.lang.IllegalStateException: missing behavior definition for the preceding method call:
Menu.getName()
Usage is: expect(a.foo()).andXXX()

I'm not sure what you wanted to do. To comment one of the comment, EasyMock isn't strict. It is whatever you want.
If you want a Mockito style mock, you will use niceMock.
Then, about your code. I feel like you want to record a call to setName. And then want to make sure the XmlParseUtility.createLinesToParse is working as expected. If I'm right, you want this code:
Menu menu = EasyMock.createNiceMock(Menu.class); // unrecorded methods will return null
menu.setName("name"); // recording a call to setName
replay(menu); // done with recording, going in replaying
assertEquals(angularLines.toString(), XmlParseUtility.createLinesToParse(menu).toString());
verify(menu); // if you want to make sure setName was called

If you are actually trying to stub the static XmlParseUtility.createLinesToParse() method call, then the PowerMock library is what you are looking for.
// instantiate angularLines and menu
PowerMock.mockStatic(XmlParseUtility.class);
EasyMock.expect(XmlParseUtility.createLinesToParse(menu)).andReturn(angularLines);
PowerMock.replay(XmlParseUtility.class);
// invoke test subject
PowerMock.verify(XmlParseUtility.class);
PowerMock also requires that the test be run using their runner and that the class containing the static method be "prepared". For more information, check out their documentation

Related

Using Mockito.when() to mock and verify vs mockito.verify

Imagine you have method someMethod, how would you go by to test it?
Mockito.when(someClass.someMethod(someParam)).thenReturn(someValue);
var bar = foo() // SUT: ends upp calling someMethod somewhere in the stack
assertThat(bar).isEqualTo(someValue);
vs
Mockito.when(someClass.someMethod(someParam)).thenReturn(someValue);
var bar = foo() // SUT: ends upp calling someMethod somewhere in the stack
verify(someClass, times(1)).someMethod(someParam)
assertThat(bar).isEqualTo(someValue);
It is true that the Mockito.when is "kind of" verifying that someClass.someMethod is being called with the correct arguments. Personally I like the idea of having clear assertions/verifications so that the tests can serve as a form of documentation. I don't like giving my mocks double-responsibilities, I want to keep my mocks just simply as "mocks".
So back to my question.
What is the preferred way, using Mockito.when combined with Mockito.verify or only Mockito.when?
When defines the behaviour of the Mock - declaratively defining the way the mock will respond when methods are invoked with different parameters.
Verify is used to check whether the Mock has been interacted with in various ways.
Here are some URLS to the official Mockito documentation, which I hope will help.
Stubbing - with when
Argument matchers
Verification in order
Making sure interaction(s) never happened
on mock
It's probably worth performing a search for some other examples.
I think this question has been answered in https://stackoverflow.com/a/35301264/473064.
The summary is:
In short, it is considered good Mockito style to explicitly verify only the interactions that can't be implied from well-crafted stubs and postcondition assertions. They may be good calls for otherwise-unmeasurable side effects—logging code, thread executors, ArgumentCaptors, multiple method calls, callback functions—but generally should not be applied to stubbed interactions.
One point that I would add is that sometimes if we want to do a verifyZeroInterations to ensure that no unexpected calls occurred, we would have to first exhaust the known calls by verifying them.
What I usually do is to perform the simplest verify(mock, times(n)).someMethod(anyClass()) as generally as possible without repeating the more specific argument matching that I have already specified in the stubbing, which reduces the duplication as much as possible.
Example:
when(someObject.someMethod(eq("abc"))).thenReturn(someValue);
when(someObject.someMethod(eq("def"))).thenReturn(otherValue);
when(someObject.someMethod(endsWith("suffix"))).thenReturn(anotherValue);
var bar = foo();
assertEquals(expectedBar, bar);
verify(someObject, times(3)).someMethod(anyString());
verifyZeroInteractions(someObject);
Regarding your concern in the comment:
The problem I see is, if a new developer reads the test, they won't know the subbed method is part of the verification process.
The stubbed method is not part of the verification process. It's part of the test case setup, i.e., the Given step.
I think your example might be a little bit misleading. The final output from foo() is usually a transformation of the response from someMethod, i.e., someValue in the example. So if the stubbed method is not called and returned with the correct value, the test would have failed anyway. The said developer would then have to look at the mocking and understand how the test case works.
In the updated example below, there is no need to verify that someMethod is called because if it didn't get called, the assertion would fail.
Mockito.when(someClass.someMethod(someParam)).thenReturn(someValue);
var bar = foo() // SUT: ends upp calling someMethod somewhere in the stack
var expectedValue = // a value depending on `someValue`
assertThat(bar).isEqualTo(expectedValue);

Use of chaining OngoingStubbing Mockito?

In Mockito when we try to mock a method call, let's say we configure something like this
when(exampleClass.getOutputString(anyString())).thenReturn("output1");
This is all understandable. But my question is what is the reason this thenReturn("output1") method returns an OngoingStrubbing object (same as what when(exampleClass.getOutputString(anyString())) method returns), so that we can do something like this
when(exampleClass.getOutputString(anyString())).thenReturn("output1").thenReturn("output2");
or
when(exampleClass.getOutputString(anyString())).thenReturn("output1").thenThrow(new IllegalArgumentException());
However, both the above cases, when using the mock, it only returns "output1" and that's all the story. Anyone knows, why this chaining feature is present, and what are the uses of it? Kind of same thing applies to doReturn() too.
This means for the first call gives ouput1 and in the second call gives output2, and so on.
when(exampleClass.getOutputString(anyString())).thenReturn("output1").thenReturn("output2");
, The second one you need to reach one condition in the target test class so gives
output1 for the first case but in the second one you want to fail to test for example
try-catch clause or see if the code cover the broken scenarios like exceptions
when(exampleClass.getOutputString(anyString())).thenReturn("output1").thenThrow(new IllegalArgumentException());

Add extra processing via annotations

I'm making a small project and I'm currently stuck on a way to achieve one of the capabilities I need.
Basically I want a method to execute when I'm calling an annotated method.For example
#PrintAnnotation
public void print(){
System.out.println("inside method");
The print annotation would just print extra test, so on calling the above method I would like to get
"Used print annotation"
"Inside method"
That's all.
I'm looking into the annotation processor API but there is no documentation anywhere except reading the javadoc which is crazy, and if I understand correctly its compile only so you cant change the original classes, only add.
I also found answers suggesting to use reflection, but to use reflection I need code triggered that checks if the method is annotated, but to do that I have to add an extra method to every method in the program, like
public void print(){
checkAnnotation();
System.out.println("test");
}
But I need it to work with only adding the annotation, not hundreds of one lines in every method of every class.
It is not possible through "only annotation" with no third party libraries and no custom code.
Annotation is only an annotation and nothing else.
It means you have to have those print and checkAnnotation methods which will detect presence of your Annotation on desired Target (Class,Method, Field...) and do what you'd like to. System.out.println("test"); definitely will not do that.
If you go with those print and checkAnnotation methods - create an utility with those methods and call print from anywhere instead of System.out.println.
But actually, what you try to achieve is about AOP. Your custom annotation can be used with it.
Then, you tagged question with spring tag, do you use Spring? It is a set of third party libraries and has AOP.

Multiple thenReturn not working properly in the Mockito

I'm testing a method that call same method (db.getData()) twice. But I must return two different values.
Mockito.when(db.someMethod()).thenReturn(valueOne).thenReturn(valueTwo);
Then I tried out multiple thenReturn().
Unfortunately I'm getting only valueTwo for first & second db.getData() method call.
You are not showing a lot of context but here are some ideas:
make sure db is really a mock object
use the debugger to check if db.someMethod() is called twice as you expect
You can also use thenReturn(valueOne, valueTwo); although that should not make a difference
I suspect that your method is called more than twice and that you are missing the first invocation (which returns valueOne) and only looking at subsequent invocations (which will all return valueTwo).
See the API:
//you can set different behavior for consecutive method calls.
//Last stubbing (e.g: thenReturn("foo")) determines the behavior of further consecutive calls.
when(mock.someMethod("some arg"))
.thenThrow(new RuntimeException())
.thenReturn("foo");
It's probably you are debugging and when you want to fetch the data of the breakPoint line, you are fetching from mock, so it will return one of it's thenReturn() parameters, so when you resume the test, it will test it with the second parameter.
I recommend you if you doubt it's working properly, one time fetch all thenReturn() items and after that you agree they're OK, start the test again with no tracing thenReturn() items.

How to assert that methods are called with mockito

I want to ask more of a conceptual question related to testing. I am using Mockitos for my unit testing.
I have a method that does bunch of things. All the methods it calls internally are void methods, which in turn will do some other actions. The method under question can complete with exception or without exception. There is no scope for writing assert statements as it mostly calls void methods. Also, I have written independent unit test for all other methods of this class.
My question is if I need test coverage, I should write test case for all methods. But, I do not find any valid assert for one of my method. The method under question is an important method from unit test coverage perspective. When I run my test, I do see in logs that the methods executes fine but there is really nothing to assert. What should I do in such a situation?
1) Leave the method as is without any asserts? It still is checking if everything is working as expected
2) Create 2 methods one that expects exception ( Negative Testcase) and one regular test method with no asserts. ( This is to basically show I have covered both positive and negetive scenario). I still do not have any asserts here.
Is this the right approach to take or there is a better way for dealing with this problem?
If you don't have anything worth asserting, you can try verification instead.
verify(someMock, times(x)).someMethod();
More on verification with Mockito in the documentation: https://mockito.googlecode.com/hg-history/1.5/javadoc/org/mockito/Mockito.html
Why isn't there anything to assert? Let A be the universe if you run your method. Let B be the universe if you don't run your method. If A == B then stop calling the method, it's not doing anything. If A != B then assert that whatever is different about them is true.
i.e., what is your method actually doing? That should be part of your test.

Categories