Skip method call in junit test case using EasyMock? - java

I am writing a test case for "headersection()" method. Inside this method, it is calling a constructor of another class, let's say "InformationHeader.java" class. Inside this constructor, it will invoke one method called as "makepage()". Again "makepage()" method will invoke another "createpage()" method.
I wanted to skip the method call to "createpage()" in my test case. Please suggest how to achieve this scenario?
private void headersection(Object child) {
headerobject = new InformationHeader(parameter_1, parameter_2, parameter_3, parameter_4);
//lines of code
}
//InformationHeader.java
public InformationHeader(parameter_1, parameter_2, parameter_3, parameter_4) {
//lines of code
makepage();
//lines of code
}
public final void makepage() {
//lines of code
createpage(); //I wanted to skip this method call
}
Any help would be appreciated
Thanks

I hope I got your question, but as I mentioned in my comment, you could change the method a bit and create a method which could be mocked.
void headersection(Object child) {
headerobject = getInformationHeader(/*parameter*/)
//lines of code
}
InformationHeader getInformationHeader(/*parameter*/) {
return new InformationHeader(parameter_1,parameter_2,parameter_3,parameter_4);
}
I don't know your class name in which the headersection mehtod is stored, lets say SectionService. Now, you could use Mockito to create a so called spy
#InjectMock
SectionService serviceToTest;
SectionService spyServiceToTest = Mockito.spy(serviceToTest);
InformationHeader spyInformationHeader = Mockit.spy(new InformationHeader(/*parameter*/));
Now you can mock a call inside of the tested class:
Mockito.doReturn(spyInformationHeader).when(spyServiceToTest).getInformationHeader(//parameter);
Mockiot.doNothing().when(spyInformationHeader).createpage();
Here is a stackoverflow question which is dealing with spy calls and
here is the Mockito documentation.
I hope this helps, greetings Matthias

The answer using spies doesn't work. The new InformationHeader(/*parameter*/) will call createpage. You will have the same problem with EasyMock.
The problem is that you can't mock a method before creating a partial mock. So when the constructor is calling a method, it doesn't work.
I would probably rethink my design if I was you. But not having the full picture, I can't give advice on that.
Keeping the current design, the easiest is actually to do a manual mock. It goes like this.
public class MyTest extends EasyMockSupport {
#Test
public void test() {
InformationHeader header = new InformationHeader("a", "b", "c", "d") {
#Override
public void createpage() {
// do nothing
}
};
ToTest toTest = partialMockBuilder(ToTest.class)
.withConstructor()
.addMockedMethod("createHeader")
.mock();
expect(toTest.createHeader()).andReturn(header);
replayAll();
toTest.headersection(null);
}
}
class ToTest {
void headersection(Object child) {
InformationHeader headerobject = createHeader();
}
InformationHeader createHeader() {
return new InformationHeader("a", "b", "c", "d");
}
}
class InformationHeader {
public InformationHeader(String p1, String p2, String p3, String p4) {
makepage();
}
public final void makepage() {
createpage();
}
public void createpage() {
throw new RuntimeException("Should not be called");
}
}

Related

Java MockedStatic method is still called

So I'm using MockedStatic<> to mock a static method but it seems like the item inside is still getting called? If this is the case, what's the point of mocking it? I have the following setup:
Object being tested:
public class ObjectBeingTested {
public void methodBeingTested() {
Object obj = ObjectInQuestion.getInstance(new Object(), "abc");
// do stuff with obj
}
}
The object with static method:
public class ObjectInQuestion {
public static ObjectInQuestion getInstance(Object obj, String blah) {
someLocalVar = new FileRequiredObject();
// we get NullPointerException here cuz in test env, no files found
}
private ObjectInQuestion() {
// private constructor to make people use getInstance
}
}
Test code:
public class MyTestClass {
MockedStatic<SomeClass> mySomeClass;
#Mock ObjectInQuestion mMockedObjectInQuestion;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
mySomeClass = mockStatic(SomeClass.class);
when(SomeClass.getInstance(any(), anyString()).thenReturn(mMockedObjectInQuestion);
}
#After
public void tearDown() {
mySomeClass.close();
}
}
My questions are the following:
Why calling ObjectInQuestion.getInstance() in the test class, it's totally fine but when it's being called from ObjectBeingTested, it runs the real construction?
I tried to use mockConstruction on FileRequiredObject, it still actually construct the object ... why?
You're using the wrong syntax for stubbing the static method. You want something like
mySomeClass.when(
()->SomeClass.getInstance(any(), anyString()))
.thenReturn(mMockedObjectInQuestion);
More information available here
Assuming MockedStatic<SomeClass> mySomeClass; is actually MockedStatic<ObjectInQuestion> mySomeClass;, I would try to simplify the setup using a classic try block.
In any case, sharing the actual test method might be able to shine some light. ;)

How to mock void method using EasyMock and then how to test it using assert?

I need to unit test a function, which makes an inner call of another void method.
Class TestClass {
public void testMethod() {
someOtherClass.testMethod(); // This is void method
}
}
I need to mock someOtherClass.testMethod() and then verify testMethod of TestClass using assert.
Sorry for my post if it is confusing. Let me make it more clear. My intention is -
public void testMethodTest() {
TestClass tC = new TestClass(); SomeOtherClass obj = EasyMock.createNiceMock(SomeOtherClass.class);
tC.set(obj);
obj.testMethod();
EasyMock.expectLastCall().andAnswer(new IAnswer() {
public Object answer() { // return the value to be returned by the method (null for void)
return null;
}
});
EasyMock.replay(obj);
tC.testMethod(); // How to verify this using assert.
}
What you wrote is working. However, it is overly complicated and you are not verifying that the void method was actually called. To do that, you need to add EasyMock.verify(obj); at the end.
Then, one important thing is that if you call a void method before the replay, it records a call. No need to add an expectLastCall. Also, you could have used expectLastCall().andVoid() instead of the IAnswer.
Here is how I would write it:
#Test
public void testMethodTest() {
TestClass tC = new TestClass();
SomeOtherClass obj = mock(SomeOtherClass.class); // no need to use a nice mock
tC.set(obj);
obj.testMethod();
replay(obj);
tC.testMethod();
verify(obj); // Verify testMethod was called
}

Verifiying time between calls with mockito

I've read a lot of documentation, examples on the net, and still have no idea of how to do it. (if it could be done).
I need to test a method in a object called by other thread and it has a requirement of time. So my original idea was creating a spy, override the method and do the task, but the problem is, I can't access test method variables from the spy. So I can't get the value returned from System.currentTimeMillis() from the test method and proccess it to get the difference within times.
I will write some abstract code describing the situation so you could understand better the situation.
#Test
public void test()
{
Objectspied spy = Mockito.spy(new Objectspied(Parameters p));
long[] timesRetrieved = new long[numberOfCallsIExpect];
//here goes the tricky part
Mockito.doAnswer(new Answer<void>(){
#override
public methodCalledFromAnotherThread(int index)
{
//what i wish to do but can't do it
timesRetrieved[i] = System.currentTimeMilis();
}
}
).when(spy).methodCalledFromAnotherThread(anyInt);
//here initialize the thread who call it
//then proccess al time diferences and get sure they are what i've expected
}
public class AnotherThread
{
ObjectSpied reference;
public void run()
{
for (int i=0;i<repeat;i++)
{
reference.methodCalledFromAnotherThread(i);
Thread.sleep(1000);
}
}
}
I'm new to Mockito so i know syntax is totally wrong but i can fix that by myself, all i need to know is:
Is there any way to do it with Mockito?
If so, can you point me to the right direction?
You should be fine this way. Just make sure:
1) You mark the array as final
2) Properly implement the answer interface method
final long[] timesRetrieved = new long[size];
Mockito.doAnswer(new Answer<Void>() {
#Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
int index = invocationOnMock.getArgumentAt(0, Integer.class);
timesRetrieved[index] = System.currentTimeMillis();;
return null;
}
}
).when(spy).methodCalledFromAnotherThread(Mockito.anyInt());

Mock inherited method in Mockito Java

My class structure is as follows:
public class MyParentClass {
void doSomethingParent() {
System.out.println("something in parent");
}
}
public class MyClass extends MyParentClass {
protected String createDummyRequest(Holder myHolder) {
//...
super.doSomethingParent();//I want to avoid this
//...
callingDB();
return "processedOutput";
}
private void callingDB() {
System.out.println("Calling to DB");
}
}
Then my unit test:
public class UnitTest {
public void testCreateDummyRequest() {
//create my mock holder
Holder mockHolder = new Holder();
MyClass mockObj = Mockito.mock(MyClass.class);
//mock doSomethingParent()
//mock callingDB()
//as mockObj is a fully mock, but I need to run my real method
//Mockito.when(mockObj.createDummyRequest(mockHolder)).thenCallRealMethod();
mockObj.createDummyRequest(mockHolder);
//Problem: doSomethingParent() is getting called though I have mocked it
}
}
How do I prevent the calling of the super.doSomethingParent() in my method? (method which I am writing my test)
With this class structure mocking and testing is real hard. If possible, I'd advice to change the structure as in mist cases a class structure that's hard to mock and test is equally hard to extend and maintain.
So if you could change your class structure to something similar to:
public class MyClass {
private DoSomethingProvider doSomethingProvider;
private DbConnector dbConnector;
public MyClass (DoSomethingProvider p, DbConnector c) {
doSomethingProvicer = p;
dbConnector = c;
}
protected String createDummyRequest(Holder myHolder){
//...
doSomethingProvider.doSomethingParent();
//...
dbConnector.callingDB();
return "processedOutput";
}
}
Then you could easily create your instance with mocks of DoSomethingProvider and DbConnector and voila....
If you can't change your class structure you need to use Mockito.spy instead of Mockito.mock to stub specific method calls but use the real object.
public void testCreateDummyRequest(){
//create my mock holder
Holder mockHolder = new Holder();
MyClass mockObj = Mockito.spy(new MyClass());
Mockito.doNothing().when(mockObj).doSomething();
mockObj.createDummyRequest(mockHolder);
}
Note: Using the super keyword prevents Mockito from stubbing that method call. I don't know if there is a way to stub calls to super. If possible (as in you didn't override the parent method in your class), just ommit the keyword.
I faced similar issue, so I find out that using spy() can hepld.
public class UnitTest {
private MyClass myObj;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
myObj= spy(new MyClass());
}
#Test
public void mockedSuperClassMethod(){
doNothing().when((MyParentClass )myObj).doSomethingParent();
//...
}
}
This approach works for me.
I found another approach, which turned out to be very useful in my case.
In the case I had, I needed to create a new class extending another, which included a very complex (legacy code) protected final method. Due to the complexity, it wasn't really possible to refactor to use composition, so here's what I came up with.
Let's say I have the following:
abstract class Parent {
public abstract void implementMe();
protected final void doComplexStuff( /* a long parameter list */) {
// very complex legacy logic
}
}
class MyNewClass extends Parent {
#Override
public void implementMe() {
// custom stuff
doComplexStuff(/* a long parameter list */); // calling the parent
// some more custom stuff
}
}
Here's how I rearranged this code:
abstract class Parent {
public abstract void implementMe();
protected final void doComplexStuff( /* a long parameter list */) {
// very complex legacy logic
}
}
interface ComplexStuffExecutor {
void executeComplexStuff(/* a long parameter list, matching the one from doComplexStuff */);
}
class MyNewClass extends Parent {
private final ComplexStuffExecutor complexStuffExecutor;
MyNewClass() {
this.complexStuffExecutor = this::doComplexStuff;
}
MyNewClass(ComplexStuffExecutor complexStuffExecutor) {
this.complexStuffExecutor = complexStuffExecutor;
}
#Override
public void implementMe() {
// custom stuff
complexStuffExecutor.doComplexStuff(/* a long parameter list */); // either calling the parent or the injected ComplexStuffExecutor
// some more custom stuff
}
}
When creating instance of MyNewClass for "production" purposes, I can use the default constructor.
When writing unit tests, however, I'd use the constructor, where I can inject ComplexStuffExecutor, provide a mock there and only test my custom logic from MyNewClass, i.e.:
class MyNewClassTest {
#Test
void testImplementMe() {
ComplexStuffExecutor complexStuffExecutor = Mockito.mock(ComplexStuffExecutor.class);
doNothing().when(complexStuffExecutor).executeComplexStuff(/* expected parameters */);
MyNewClass systemUnderTest = new MyNewClass(complexStuffExecutor);
// perform tests
}
}
At first glance, it seems like adding some boilerplate code just to make the code testable. However, I can also see it as an indicator of how the code should actually look like. Perhaps one day someone (who would find courage and budget ;) ) could refactor the code e.g. to implement the ComplexStuffExecutor with the logic from doComplexStuff from Parent, inject it into MyNewClass and get rid of inheritance.
Here is how it can be done
public class BaseController {
public void method() {
validate(); // I don't want to run this!
}
}
public class JDrivenController extends BaseController {
public void method(){
super.method()
load(); // I only want to test this!
}
}
#Test
public void testSave() {
JDrivenController spy = Mockito.spy(new JDrivenController());
// Prevent/stub logic in super.method()
Mockito.doNothing().when((BaseController)spy).validate();
// When
spy.method();
// Then
verify(spy).load();
}
Source: https://blog.jdriven.com/2013/05/mock-superclass-method-with-mockito/

PowerMock + EasyMock: private void method without invokation

Good time!
I need to substitute the class' private void method with a mock implementation, and can't to figure out how to do this. I've tried to use such a construction:
Test test = PowerMock.createPartialMock(Test.class, "setId");
PowerMock.expectPrivate(test , "setId", EasyMock.anyLong()).andAnswer(
new IAnswer<Void>() {
#Override
public Void answer() throws Throwable {
return null;
}
});
PowerMock.replay(test);
but the internal PowerMock's class called WhiteBox invokes my "setId" method which is wrong for my task. Could someone, please, suggest, how to avoid the method invokation and possibly to replace the method body with a custom one?
Finally. I've got the solution.
The problem was I missed the following annotations:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Test.class)
Anyway, it seems rather confusing that to make the PowerMock working I need to add some annotations. If that wasn't a legacy code I'd prefer Mockito.
Not quite sure that I get the question.
But for me code below works perfect and just string "Invoked!" is getting printed
and if I remove test.setS(33L); test will fail with exception:
#RunWith(PowerMockRunner.class)
#PrepareForTest(MainTest.Test2.class)
public class MainTest {
#Test
public void testName() throws Exception {
Test2 test = PowerMock.createPartialMock(Test2.class, "setS");
PowerMock.expectPrivate(test , "setS", EasyMock.anyLong()).andAnswer(
new IAnswer<Void>() {
#Override
public Void answer() throws Throwable {
System.out.println("Invoked!");
return null;
}
}).atLeastOnce();
PowerMock.replay(test);
test.setS(33L);
PowerMock.verify(test);
}
class Test2 {
long s;
private long getS() {
return s;
}
private void setS(long s) {
this.s = s;
System.out.println("Not this!");
}
}
}

Categories

Resources