I am trying to build my first EasyMock test, however I have a trivial problem that the function "mock" is not found.
Here is my pretty straightforward code:
package homework;
import org.easymock.EasyMockSupport;
import org.junit.Before;
import org.junit.Test;
import com.locusenergy.homework.Elevator;
public class ElevatorTest extends EasyMockSupport{
private Elevator elevator;
#Before
public void setUp() {
elevator = mock(Elevator.class);
}
#Test
public void testCallElevator() {
elevator.requestFloor(5);
}
}
However, I am getting an error that mock is not found. I have no idea how to fix this issue.
Your code probably will work as it is when the next version of EasyMock is released.
The user guide refers to the mock method which can be found in the master branch but is not in the latest release (3.3.1).
Depending on Documentationof EasyMock the example should look like this:
package homework;
import org.easymock.EasyMockSupport;
import org.junit.Before;
import org.junit.Test;
import com.locusenergy.homework.Elevator;
public class ElevatorTest extends EasyMockSupport{
private Elevator elevator;
#Before
public void setUp() {
elevator = createMock(Elevator.class);
}
#Test
public void testCallElevator() {
elevator.requestFloor(5);
}
}
As described here: http://easymock.org/api/org/easymock/EasyMockSupport.html
The API Docs say the methods nameis createMock thats all.
Just sharing another approach...
You can use org.easymock.IMocksControl.
Your code will look something like below
....
#Before
public void setUp() {
IMocksControl mocksControl = createControl();
elevator = = mocksControl.createMock(Elevator.class);
}
.....
I prefer using IMocksControl. As the name\api suggest controls the behavior of its associated mock object.
Note : I am using easymock version 3.1
Regards,
MB
Related
I am writing a unit test to mock a static method in the verticle but getting ClassNotPreparedException always. I think that its only possible to mock this way if only the class is static, but i have non static class. What am i missing?
I have tried various solutions like using #rule or #PowerMockIgnore
//myVerticleTest.java
package com.blabla.me.verticles;
import static com.google.common.truth.Truth.assertThat;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import io.vertx.core.Vertx;
import io.vertx.junit5.VertxTestContext;
import io.vulpx.VulpxTestBase;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.junit.runner.RunWith;
import com.blabla.me.verticles.AdditionalInformationCardVerticle;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.junit.Rule;
import com.blabla.me.verticles.st;
#RunWith(PowerMockRunner.class)
#PrepareForTest({ st.class })
#PowerMockIgnore({"org.mockito.*"})
public class myVerticleTest extends VulpxTestBase {
#Rule public PowerMockRule rule = new PowerMockRule();
private Vertx vertx;
private AdditionalInformationCardVerticle dummy;
#BeforeEach
#PrepareForTest({ st.class })
public void setUp(VertxTestContext testContext) throws Exception {
vertx = Vertx.vertx();
try {
PowerMockito.mockStatic(st.class);
PowerMockito.when(st.createClient()).thenReturn("kk");
//deploying verticle
dummy = new AdditionalInformationCardVerticle();
vertx.deployVerticle(dummy, testContext.completing());
} catch (Exception e) {
System.out.println("heyyy eroorrr : " + e);
}
}
#Test
#PrepareForTest({ st.class })
public void justnormaltest() {
cla ownclass = new cla();
String k = ownclass.createfromclass();
assertThat("kk").isEqualTo(k);
}
}
// st.java
public class st {
public static String createClient() {
return "kk";
}
}
// cla.java
public class cla {
public String createfromclass() {
return st.createClient();
}
}
I expect it to run the assertion but i always get below excpetion:
"org.powermock.api.mockito.ClassNotPreparedException:
The class com.sap.me.verticles.st not prepared for test.
To prepare this class, add class to the '#PrepareForTest' annotation.
In case if you don't use this annotation, add the annotation on class or method level. "
Here:
#PrepareForTest({ st.class })
That one goes to exactly one place: in front of your test class public class myVerticleTest.
And hint: instead of adding more and more "things" to not working code: pick any good documentation, and try to follow that to the last ; in the example code (instead of assuming that adding more and more things here or there would help).
One good starting point: the official documentation on static mocking.
And of course, the usual caveat: consider not learning about PowerMock in the first place. Instead focus on writing "easy to test" code. Far too often, people think PowerMock(ito) is the answer to their problem. When their problem in reality is their inability to write "easy to test" production code.
I want to mock a static method using PowerMockito,
public class DepedencyService {
public static int getImportantValue() {
return -4;
}
}
public class Component {
public int componentMethod() {
return DepedencyService.getImportantValue();
}
}
but it is giving me an exception.
import static org.testng.Assert.assertEquals;
import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(DepedencyService.class)
public class ComponentTest {
#Test
public void testComponentMethod() {
Component c = new Component();
PowerMockito.mockStatic(DepedencyService.class);
EasyMock.expect(DepedencyService.getImportantValue()).andReturn(1);
assertEquals(1, c.componentMethod());
}
}
The exception :-
java.lang.IllegalStateException: no last call on a mock available at
org.easymock.EasyMock.getControlForLastCall(EasyMock.java:520) at
org.easymock.EasyMock.expect(EasyMock.java:498)
Can anyone please help me? Why is this failing? I am new to PowerMockito and does not know what to do here!
Your main problem is that you're writing STUPID code (like most of us did at the beginning) where you rather should write SOLID code.
Using Powermock is just a surrender to this bad design.
Yes, classes having only static methods are called utility classes.
But you should get over this misconception that classes providing common behavior should have (only) static methods.
As a rule of thumb there should be only one non private static method in your entire program, and this is main().
You appear to be mixing mocking frameworks.
You need to properly arrange the static dependencies before exercising the test
Since PowerMockito is used to mock the static class then you should use Mockito to arrange the expected behavior
For example
#RunWith(PowerMockRunner.class)
#PrepareForTest(DepedencyService.class)
public class ComponentTest {
#Test
public void testComponentMethod() {
//Arrange
int expected = 1;
PowerMockito.mockStatic(DepedencyService.class);
Mockito.when(DepedencyService.getImportantValue()).thenReturn(expected);
Component subject = new Component();
//Act
int actual = subject.componentMethod();
//Assert
assertEquals(expected, actual);
}
}
That said, I would advise not having your code tightly coupled to static dependencies. It makes for difficult to test code.
This is a follow-on question to this one.
My problem is: I upgraded our environment to newer versions of JUnit, Mockito, ... Unfortunately, I was running my local tests with a up-to-date IBM JRE. Then we found out that in our build environment, all our Mockito tests are now failing with
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: interface java.util.concurrent.ExecutorService.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
Followed by:
Early IBM virtual machine are known to have issues with Mockito, please upgrade to an up-to-date version.
OK; so I spent some time to A) figure within a test that it is run by an outdated JRE so I could B) then have all tests skipped. In the end; I put together the below code.
But some notes upfront: I verified that my forceJUnit...() method really throws that exception when running with an IBM Java8 JRE that has SR1 or SR2 level. My point is: although the method should throw ... when I run that test case, I am still hitting the Mockito exception about "can not mock"!
Any idea what I am doing wrong here?
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
class Helper {
public static void forceJUnitToIgnoreTestForJava8SR1() {
Assume.assumeFalse("Ignoring test when running with JRE SR1", isJava8SR1());
}
private static boolean isJava8SR1() {
String fullVersion = System.getProperty("java.fullversion", "");
return fullVersion.contains("R28_Java8_SR1");
}
}
#RunWith(MockitoJUnitRunner.class)
public class Mcve {
#Mock
private ExecutorService service;
#Before
public void setup() {
Helper.forceJUnitToIgnoreTestForJava8SR1();
// make the mcve do something
doAnswer(new Answer<Future<?>>() {
#Override
public Future<?> answer(InvocationOnMock invocation) throws Throwable {
return null;
}
}).when(service).submit(any(Runnable.class));
}
#Test
public void test() {
System.out.println("won't show up ;-(");
}
}
Directly call MockitoAnnotations.initMocks(this) instead of using MockitoJUnitRunner:
public class Mcve {
#Mock
private ExecutorService service;
#Before
public void setup() {
Helper.forceJUnitToIgnoreTestForJava8SR1();
MockitoAnnotations.initMocks(this);
...
}
#Test
public void test() {
System.out.println("won't show up ;-(");
}
}
Not sure here, but:
Maybe you just try to call Helper.forceJUnitToIgnoreTestForJava8SR1(); within a method marked with #BeforeClass
Or, you could change your test case and remove the #Mock annotation; and do ALL of the required configuration steps AFTER calling Helper.forceJUnitToIgnoreTestForJava8SR1(); within your setup method?
Here is probably a simple question, but I can't get Dao Mocks to work.
import com.feetme.backend.jdbi.IRecordDAO;
import com.feetme.backend.representations.Record;
import io.dropwizard.testing.junit.ResourceTestRule;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class BasicResourceTest {
private static final IRecordDAO dao = mock(IRecordDAO.class);
private final Record record = getDummyRecord();
#ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.addResource(new BasicResource(dao))
.build();
private static Record getDummyRecord(){
Record rec = new Record();
rec.setId(10);
return rec;
}
#Before
public void setup() {
when(dao.findRecordById(eq(10))).thenReturn(record);
reset(dao);
}
#Test
public void testGetId_Patient() {
Record r = dao.findRecordById(10);
assertThat(r).isEqualTo(record);
assert(r.getId() == 10)
}
In this case, both my asserts are never ok.
I also trier to put the reset call in the #After method. Same problem.
My IRecordDAO method normally simply fetches a Record in DB.
I probably missed something obvious.
Any help would be appreciated.
Here the DAO interface.
#RegisterMapper(RecordMapper.class)
public interface IRecordDAO {
#SqlQuery("sql query ...")
Record findRecordById(#Bind("id") long id);
/**
* close with no args is used to close the connection
*/
void close();
Edit: Actually the problem seems related to the eq() method. When I do something similar with a method of my dao that does not require any parameter, I don't have any problem.
When I replace eq(10) by anyInt() it works fine. I think I'll be fine with it for now but any clue is still welcome.
Finally, replacing eq(10) by 10 works fine. How is eq supposed to be used then ?
Don't reset(dao) in your setup() method. This is causing the mock dao to forget your previously configured stubbing. See the Mockito documentation on resetting mocks.
According to eq's java doc
public static <T> T eq(T value)
Object argument that is equal to the given value.
it's for Objects, while 10 is int which is a primitive type. You could try using new Integer(10), just to see if that makes any difference.
I'm trying to verify that the Collections.shuffle() method was called in one of my classes. I read through the (little) documentation on PowerMock with Mockito and read through the other SO questions that dealt with this issue and didn't get a resolution.
#RunWith(PowerMockRunner.class)
#PrepareForTest(Collections.class)
public class MyTest {
#Test
public void testShuffle() {
PowerMockito.mockStatic(Collections.class);
PowerMockito.doCallRealMethod().when(Collections.class);
Collections.shuffle(Mockito.anyListOf(Something.class));
ClassToTest test = new ClassToTest();
test.doSomething();
PowerMockito.verifyStatic(); // Verify shuffle was called exactly once
Collections.shuffle(Mockito.anyListOf(Something.class));
}
}
public class ClassToTest {
private final List<Something> list;
// ...
public void doSomething() {
Collections.shuffle(list);
// do more stuff
}
}
Given the above code, I expect the unit test pass. However, the unit test fails as follows:
Wanted but not invoked java.util.Collections.shuffle([]);
Actually, there were zero interactions with this mock.
What am I doing wrong?
Thanks
EDIT:
As per the suggestion below I tried the following, and I get the same error.
#RunWith(PowerMockRunner.class)
#PrepareForTest(Collections.class)
public class MyTest {
#Test
public void testShuffle() {
PowerMockito.mockStatic(Collections.class);
ClassToTest test = new ClassToTest();
test.doSomething();
PowerMockito.verifyStatic(); // Verify shuffle was called exactly once
Collections.shuffle(Mockito.anyListOf(Something.class));
}
}
This is a rather old question, but I'd still like to clarify that the accepted answer is in fact incorrect. By executing the following code,
PowerMockito.mockStatic(Collections.class);
Collections.shuffle(Mockito.anyListOf(Something.class));
all verifies will always pass afterwards:
PowerMockito.verifyStatic(); // Verify shuffle was called exactly once
Collections.shuffle(Mockito.anyListOf(Something.class));
even if you do not call test.doSomething(); the provided test in the answer will still pass. The correct way to test this is to actually check if the items in the List have been sorted correctly.
You can either mock/verify the java.util.Collections.shuffle([]) method or call the real implementation (with PowerMockito.doCallRealMethod()). But you can't do both.
If you remove
PowerMockito.doCallRealMethod().when(Collections.class);
the call will be verified and the test will pass.
https://powermock.googlecode.com/svn/docs/powermock-1.4.7/apidocs/org/powermock/api/mockito/PowerMockito.html#doCallRealMethod%28%29
This code works for me:
package test;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(Collections.class)
public class MyTest {
#Test
public void testShuffle() {
PowerMockito.mockStatic(Collections.class);
/* PowerMockito.doCallRealMethod().when(Collections.class); remove this line */
Collections.shuffle(Mockito.anyListOf(Something.class));
ClassToTest test = new ClassToTest();
test.doSomething();
PowerMockito.verifyStatic(); // Verify shuffle was called exactly once
Collections.shuffle(Mockito.anyListOf(Something.class));
}
}
class ClassToTest {
private List<Something> list = new LinkedList<Something>();
// ...
public void doSomething() {
Collections.shuffle(list);
// do more stuff
}
}
class Something {
}