I am writing a test using Junit + Mockito + Powermock.
I have a class like following which I want to test:
public class MyUtils {
public static Object method1() {} //I want to mock this only
public static void method2() {} //I want to keep this as is during my test.
public static void method3() {} //I want to keep this as is during my test.
}
I want to mock only method1 but not method2 or method3.
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyUtils.class)
public class MyTest {
#Before
public void setUpBeforeClass() throws Exception {
PowerMockito.mockStatic(MyUtils.class);
}
#Test
public void test1() throws Exception {
when(MyUtils.method1()).thenReturn(something);
MyUtils.method3(); //method3 is getting mocked with an empty implementation by PowerMockito
}
...
}
Can I have some methods mocked and some not be mocked i.e. they keep their original implementation during the test? Is this possible with Mockito + Powermock?
My test may not look very elegant but I have simplified my usecase before posting here.
Thank you.
Yes it is possible to mock static methods using Powermock and JUnit as below:
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.powermock.api.mockito.PowerMockito.*;
#RunWith(PowerMockRunner.class)
#PrepareForTest(IDGenerator.class)
public class UserDAOTest {
#Test
public void createShouldReturnAUserId() {
UserDAO dao = new UserDAO();
mockStatic(IDGenerator.class);
when(IDGenerator.generateID()).thenReturn(1);
int result = dao.create(new User());
assertEquals(1, result);
verifyStatic();
}
}
public final class IDGenerator {
static int i;
public static final int generateID() {
return i++;
}
}
public class UserDAO {
public int create(User user){
int id = IDGenerator.generateID();
//Save the user object to the db
return id;
}
}
public class User {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Hope it helps!
If you have way more methods that you want to keep with real implementation than ones that need to be mocked (especially when its only one in your case) then I would go for spy instead of mock:
import static org.powermock.api.mockito.PowerMockito.spy;
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyUtils.class)
public class MyTest {
#Before
public void setUpBeforeClass() throws Exception {
spy(MyUtils.class);
}
#Test
public void test1() throws Exception {
doReturn(something).when(MyUtils.class, "method1");
MyUtils.method3(); // this will be a real call
}
...
}
Now all the methods except method1 will be called with real implementation.
Related
So I am trying to run JUnit parameterized tests along with non-parameterized tests in the same test class. But I am running into one error or the other. Has anyone tried this before and were they successful in doing so? I know other runners need to be used with the #PowerMockRunnerDelegate in order to run correctly. So here's what I came up with:
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(Enclosed.class)
#PrepareForTest(Some.class)
#PowerMockIgnore("javax.management.*")
public class TestClass {
#PowerMockRunnerDelegate(Parameterized.class)
public static class ParameterizedTests {
}
#Test
public void nonParameterizedTestOne() {
}
#Test
public void nonParameterizedTestTwo() {
}
}
But I get the error:
Test class should have exactly one public zero-argument constructor
Without powermock, this situation can be easily handled with:
#RunWith(Enclosed.class)
public class TestClass {
#RunWith(Parameterized.class)
public static class ParameterizedTests {
}
#Test
public void nonParameterizedTestOne() {
}
#Test
public void nonParameterizedTestTwo() {
}
}
But I would definitely like to use powermock. Any solutions?
I had the same issue, this worked for me:
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(Enclosed.class)
#PrepareForTest({Some.class})
public class TestClass {
private static void setUpOnceForAllTests() {
}
private static void setUpForEveryTest() {
}
public static class SingleTests {
// Setup once for all single tests
#BeforeClass
public static void setUpBeforeClass() {
setUpOnceForTests();
}
// Setup for each and every single test
#Before
public void setUp() {
setUpForEveryTest();
}
#Test
public void nonParameterizedTestOne() {
}
#Test
public void nonParameterizedTestTwo() {
}
}
#PowerMockRunnerDelegate(Parameterized.class)
public static class ParameterizedTests {
// Setup once for all parameterized test
#BeforeClass
public static void setUpBeforeClass() {
setUpOnceForTests();
}
// Setup for each and every parameterized test
#Before
public void setUp() {
setUpForEveryTest();
}
#Parameterized.Parameters
public static Collection<Enum> param() {
return new ArrayList<>(Arrays.asList(Enum.values()));
}
#Parameterized.Parameter
public int param;
#Test
public void parameterizedTestOne() {
}
#Test
public void parameterizedTestTwo() {
}
}
}
I've seen how to unit test classes that use Utility classes by mocking the Static method, but I haven't been able to figure out how to unit test the actual Utility Class.
Here is the Utility Class
public class DbNameContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setDbName(String dbName){
contextHolder.set(dbName);
}
public static String getDbName(){
return (String) contextHolder.get();
}
public static void clearDbName(){
contextHolder.remove();
}
}
Here is what I've tried so far for a unit test
#RunWith(PowerMockRunner.class)
#PrepareForTest({DbNameContextHolder.class, ThreadLocal.class})
public class DbNameContextHolderTest {
#SuppressWarnings("rawtypes")
#Mock
ThreadLocal threadLocalMock;
#Before
public void init() throws Exception{
PowerMockito.whenNew(ThreadLocal.class).withNoArguments().thenReturn(threadLocalMock);
}
#Test
public void setsDBName(){
DbNameContextHolder.setDbName("someName");
verify(threadLocalMock).set("someName");
}
#Test
public void getsDbName(){
DbNameContextHolder.getDbName();
verify(threadLocalMock).get();
}
#Test
public void clearsDBName(){
DbNameContextHolder.clearDbName();
verify(threadLocalMock).remove();
}
}
How do I mock a utility class like this?
Using the suggestions in the comments I've tested the expected outcome.
#RunWith(MockitoJUnitRunner.class)
public class DbNameContextHolderTest {
#Test
public void setsAndGetsDBNameCorrectly(){
DbNameContextHolder.setDbName("someName");
String returnedName = DbNameContextHolder.getDbName();
assertEquals("someName",returnedName);
}
#Test
public void clearsDBName(){
DbNameContextHolder.setDbName("someName");
String returnedName = DbNameContextHolder.getDbName();
assertEquals("someName",returnedName);
DbNameContextHolder.clearDbName();
returnedName = DbNameContextHolder.getDbName();
assertNull(returnedName);
}
}
I am newbie in Java world, but it is very hard understand why not can I stub method of a mocked object...
#RunWith(MockitoJUnitRunner.class)
public class ChildBLLIT extends BaseInteractorIT {
#InjectMocks
private ChildBLL ChildBLL = Mockito.mock(ChildBLL.class);
#Before
public void setUp() {
ChildBLL.engine = engineMock;
}
/**
* Test of getZipStatistics method, of class ChildBLL.
*/
#Test
public void testGetZipStatistics() {
final String testZipStatisticsText = "DummyZipStatistics";
//This method will throw the null pointer exception
when(ChildBLL.engine.getZIPStatistics()).thenReturn(testZipStatisticsText);
ChildBLL.getZipStatistics();
verify(ChildBLL.engine).getZIPStatistics();
}
}
When I try to stub the getZIPStatistics() method I get always a null pointer exception, of course I get, because in the getZIPStatistics() method there is an private object, which is not mocked... it seems to me the Mockito does not mocking the private fields... and unfortunately this is from another project:
public class BaseIT {
#Mock
protected static FromOtherProject engineMock;
#Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
}
Here I mocked the engine variable, but then how can I mock/stub the getZIPStatistics() method? This is this method:
public class FromOtherProject {
//...
public final String getZIPStatistics() {
return ZIPStatistics.toString();
}
}
What can I do?
Let's assume a simple class...
public class Account {
public String getPassword() {
return "abc";
}
}
...and simple class that contains it...
public class AccountHolder {
private Account account;
public String getAccountPassword() {
return this.account.getPassword();
}
}
So now we have a simple base class for all Account based tests...
public class AccountBasedTest {
#Mock
protected Account account;
}
...and a class that actually tests the AccountHolder...
#RunWith(MockitoJUnitRunner.class)
public class AccountHolderTest extends AccountBasedTest {
#InjectMocks
private AccountHolder accountHolder;
#Test
public void getAccountPasswort_must_return_account_password() {
Mockito.when( this.account.getPassword() ).thenReturn ("xyz");
Assert.assertEquals("xyz", this.accountHolder.getAccountPassword());
}
}
And that's all. The #InjectMocks, etc. annotations will also look in the superclasses, so you get your mocked account and that account will be put into your AccountHolder. No need to call MockitoAnnotations.initMocks. It shouldn't hurt, but it's not needed because you are using the MockitoJUnitRunner already, which does exactly that.
I want to test this class which calls a method of interface using anonymous class.
public class ClassToTest
{
public void methodToTest()
{
InterefaceToMock interefaceToMockReference = new InterefaceToMock() {
#Override
public int methodToMock()
{
return 0;
}
};
interefaceToMockReference.methodToMock();
}
}
This is the interface
public interface InterefaceToMock
{
public int methodToMock();
}
I am using this approch to check it methodToMock is called or not
import static org.junit.Assert.*;
import org.junit.Test;
import mockit.FullVerificationsInOrder;
import mockit.Mocked;
import mockit.NonStrictExpectations;
public class TestAClass
{
#Mocked InterefaceToMock interefaceToMockReferenceMocked;
#Test
public void test1()
{
new NonStrictExpectations()
{
{
interefaceToMockReferenceMocked.methodToMock();times=1;
}
};
(new ClassToTest()).methodToTest();
new FullVerificationsInOrder(interefaceToMockReferenceMocked)
{
};
assertTrue(true);
}
}
But test case fails.
Can anyone help.
Your original test was almost correct. It declared the mock field as simply being #Mocked, which merely gives you a single mocked instance implementing the interface, and this is not the one used by the code under test. The JMockit API has another mocking annotation, however, which extends mocking to all implementation classes from a given base type, and by default affects all instances of said classes. So, the test should be changed as follows:
public class TestAClass
{
#Capturing InterfaceToMock anyImplementingInstance;
#Test
public void test1()
{
new ClassToTest().methodToTest();
new Verifications() {{
anyImplementingInstance.methodToMock();
}};
}
}
In the general case, if you have an class and you want to check whether a method on a Mock of that class is called, you use Mockito.verify.
For example:
public class AppTest {
#Test
public void testMe() {
final ITest iTest = Mockito.mock(ITest.class);
final CUT cut = new CUT(iTest);
cut.doStuff();
Mockito.verify(iTest).someStuff();
}
interface ITest {
void someStuff();
}
class CUT {
private final ITest iTest;
CUT(ITest iTest) {
this.iTest = iTest;
}
public void doStuff() {
iTest.someStuff();
}
}
}
Here, the test is whether ITest.someStuff() is called from CUT.doStuff().
Your example is undecipherable...
I'm new to mock testing.
I want to test my Service method CorrectionService.correctPerson(Long personId).
The implementation is not yet written but this it what it will do:
CorrectionService will call a method of AddressDAO that will remove some of the Adress that a Person has. One Person has Many Addresses
I'm not sure what the basic structure must be of my CorrectionServiceTest.testCorrectPerson.
Also please do/not confirm that in this test i do not need to test if the adresses are actually deleted (should be done in a AddressDaoTest), Only that the DAO method was being called.
Thank you
Cleaner version:
#RunWith(MockitoJUnitRunner.class)
public class CorrectionServiceTest {
private static final Long VALID_ID = 123L;
#Mock
AddressDao addressDao;
#InjectMocks
private CorrectionService correctionService;
#Test
public void shouldCallDeleteAddress() {
//when
correctionService.correct(VALID_ID);
//then
verify(addressDao).deleteAddress(VALID_ID);
}
}
A simplified version of the CorrectionService class (visibility modifiers removed for simplicity).
class CorrectionService {
AddressDao addressDao;
CorrectionService(AddressDao addressDao) {
this.addressDao;
}
void correctPerson(Long personId) {
//Do some stuff with the addressDao here...
}
}
In your test:
import static org.mockito.Mockito.*;
public class CorrectionServiceTest {
#Before
public void setUp() {
addressDao = mock(AddressDao.class);
correctionService = new CorrectionService(addressDao);
}
#Test
public void shouldCallDeleteAddress() {
correctionService.correct(VALID_ID);
verify(addressDao).deleteAddress(VALID_ID);
}
}