For my project, I am working on power mock framework for unit testing.
I am facing an issue, I have mocked a static method, but still, it is calling the real method. I have set up the problem with simple classes. Please help to resolve the issue.
This is the Test that is being tested and it has a static method.
package in.service;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionClass {
public static boolean getValue() throws SQLException {
Connection connection = DriverManager.getConnection("", "", "");
return connection == null;
}
}
This is the test class.
package in.service;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
#RunWith(PowerMockRunner.class)
#PrepareForTest({DriverManager.class})
public class ConnectionClassTest {
#Mock
private Connection connection;
#Before
public void setUp() {
PowerMockito.mockStatic(DriverManager.class);
}
#Test
public void check_Value_WhenConnectionIsNotPresent() throws SQLException {
when(DriverManager.getConnection(anyString(), anyString(), anyString())).thenReturn(connection);
ConnectionClass.getValue();
}
#Test
public void check_Value_WhenConnectionIsPresent() throws SQLException {
when(DriverManager.getConnection(anyString(), anyString(), anyString())).thenReturn(null);
ConnectionClass.getValue();
}
}
When I try to run these tests, DriverManager's actual connection method is called. Ideally, this method shouldn't be called.
Please help here if I am doing anything wrong here.
Related
I have to write a unit-test for the following method in class VPartnerExtMapper (VPartnerExtMapper.java):
import org.jdbi.v3.core.mapper.RowMapper;
import org.jdbi.v3.core.statement.StatementContext;
import java.sql.ResultSet;
import java.sql.SQLException;
public class VPartnerExtMapper implements RowMapper<VPartnerExt> {
#Override
public VPartnerExt map(ResultSet rs, StatementContext ctx) throws SQLException {
int i = 1;
VPartnerExt result = new VPartnerExt();
result.setTecClient(rs.getLong(i++));
result.setPartnerId(rs.getLong(i++));
result.setTecVersionNr(rs.getLong(i++));
result.setName(rs.getString(i++));
return result;
}
}
My code for the unit-test so far (VPartnerExtMapperTest.java) :
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.sql.ResultSet;
import java.sql.SQLException;
#RunWith(JUnit4.class)
public class VPartnerExtMapperTest {
#Mock
private ResultSet resultSet;
#Mock
StatementContext ctx;
#Test
public void map() throws SQLException {
ResultSet resultSet = mock(ResultSet.class);
when(resultSet.getString("NAME")).thenReturn("Michael");
VPartnerExt result = new VPartnerExtMapper().map(resultSet, ctx);
assertEquals("Michael", result.getName());
}
}
(Please let me know if I missed something and need to put it in the explanation before downgrading the question.)
I am writing tests and I was looking to mock the result of the kafka admin client, when a topic is created.
I am using Mockito to write my unit tests.
Here is the test code:
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ExecutionException;
import org.apache.kafka.clients.admin.Admin;
import org.apache.kafka.clients.admin.CreateTopicsResult;
import org.apache.kafka.clients.admin.ListTopicsResult;
import org.apache.kafka.common.KafkaFuture;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Mock;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.main.Launch;
import io.restassured.RestAssured;
import io.restassured.filter.log.RequestLoggingFilter;
import io.restassured.filter.log.ResponseLoggingFilter;
#QuarkusTest
public class AppTest {
#InjectMocks
private App mockApp;
#Mock
private Client mockClient;
#Mock
private Database mockDatabase;
#Mock
private Admin mockKafkaAdmin;
#Mock
private ListTopicsResult mockListTopicResult;
#Mock
private KafkaFuture<Set<String>> mockKafkaFuture;
#Mock
private KafkaFuture<Void> mockKafkaFutureVoid;
#Mock
private Set<String> mockSet;
#Mock
private CreateTopicsResult mockCreateTopicResult;
#Mock
private Map<String, KafkaFuture<Void>> mockKafkaTopicResult;
#BeforeAll
public static void setupAll() {
RestAssured.filters(new RequestLoggingFilter(), new ResponseLoggingFilter());
}
#BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
}
#Test
#Launch(value = {}, exitCode = 1)
public void testLaunchCommandFailed() {}
#Test
public void testCreateTopic() throws InterruptedException, ExecutionException {
Mockito.when(mockClient.getKafka()).thenReturn(mockKafkaAdmin);
Mockito.when(mockClient.getKafka().createTopics(Mockito.anyList())).thenReturn(mockCreateTopicResult);
Mockito.when(mockCreateTopicResult.values()).thenReturn(mockKafkaTopicResult);
Mockito.when(mockKafkaTopicResult.get("meme.transmit.test")).thenReturn(mockKafkaFutureVoid);
mockApp.createTopic("test");
Mockito.when(mockClient.getKafka().listTopics()).thenReturn(mockListTopicResult);
Mockito.when(mockClient.getKafka().listTopics().names()).thenReturn(mockKafkaFuture);
Mockito.when(mockClient.getKafka().listTopics().names().get()).thenReturn(mockSet);
Assertions.assertTrue(mockApp.containsTopic("test"));
}
// ...
}
I get a nullpointer error when this line is called in the production code:
Mockito.when(mockCreateTopicResult.values()).thenReturn(mockKafkaTopicResult);
But as you can see I mocked it with mockKafkaTopicResult. What might I be missing here? Also is there an easier method to work with KafkaAdminClient when writing unit tests?
Mockito.when(mockClient.getKafka().createTopics(Mockito.anyList()))
.thenReturn(mockCreateTopicResult);
The issue was that I was using anyList(), when the createTopics() only accepts Collections.
The fix: Mockito.anyCollections()
I am attempting to Junit test (IDE: Intellij) Method inside a class called "ManagementDashboardBean" called: (Method name): init()
The method contains FaceContext and Session. I tried the following: https://codenotfound.com/mockito-unit-testing-facescontext-powermock-junit.html
but am still running into issues. I am using Mockito and PowerMockito to help but cannot figure out my init() is saying Null Pointer Exception (NPE). Any guidance would be greatly appreciated. Thanks
P.S the end goal is to show proper test code coverage of this method.
public void init() {
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession)context.getExternalContext().getSession(false);
userInfo = (UserSessionInfo)session.getAttribute(ConstantsUtil.USER_INFO);
startDt = FDUtil.toDate(FDUtil.toStartOfMonth(userInfo.getCurrentDateMillis()));
endDt = FDUtil.toDate(FDUtil.toEndOfMonth(userInfo.getCurrentDateMillis()));
autoCompleteDate = false;
}
Current JUnit Test
package view.managed.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
import com.sun.jdi.connect.Connector;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest({FacesContext.class})
public class ManagementDashboardBeanTest {
private ManagementDashboardBean someBean;
#Mock
private FacesContext facesContext;
#Mock
private ExternalContext externalContext;
#Before
public void setUp() throws Exception {
someBean = new ManagementDashboardBean();
//mock all static methods of FaceContext using PowerMockito
PowerMockito.mockStatic(FacesContext.class);
when(FacesContext.getCurrentInstance()).thenReturn(facesContext);
when(facesContext.getExternalContext()).thenReturn(externalContext);
}
#Test
public void testInitContext() {
//create Captor instances for the userInfo
// ArgumentCaptor<String> clientIdCapture = ArgumentCaptor.forClass(String.class);
// ArgumentCaptor<HttpSession> session = ArgumentCaptor.forClass(HttpSession.class);
// Run the method being tested
// someBean.init();
// verify(facesContext).addMessage(clientIdCapture.capture(), (FacesMessage) session.capture());
}
}
The actual .java source file starts with:
public class ManagementDashboardBean extends EntityManagerService implements Serializable {
private static final Logger LOG = LoggerFactory.getLogger(ManagementDashboardBean.class);
The right after is this, which confuses the hell out of me:
public ManagementDashboardBean() {
init();
}
What I have added so far:
import static org.junit.Assert.*;
import javax.faces.context.FacesContext;
import mil.af.fd.view.managed.services.EntityManagerService;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;
import java.io.Serializable;
#RunWith(MockitoJUnitRunner.class)
#PrepareForTest({FacesContext.class})
public class ManagementDashboardBeanTest {
private ManagementDashboardBean dashboard;
private Serializable serializableMock;
private EntityManagerService entityManagerServiceMock;
#BeforeClass
public static void before() {
System.out.println("Before Class");
}
#Before
public void setUp() throws Exception {
entityManagerServiceMock = Mockito.mock(EntityManagerService.class);
serializableMock = Mockito.mock(Serializable.class);
dashboard = new ManagementDashboardBean(serializableMock);
}
#Test
public void testInitContext() {
// dashboard.init();
System.out.println("Test 1");
}
}
In Spring boot framework, I'm finding a difficulty with the controller Unit testing using JUnit and Mockito. I want to test this method. How to test DELETE Request method:
// delete application
Controller class
#DeleteMapping("/applications")
public String deleteApplicationByObject(#RequestBody Application application) {
applicationService.deleteById(application.getId());
return "Deleted";
}
// delete application
Service class
#Override
#Transactional
public String removeById(Long id) {
dao.deleteById(id);
return "SUCCESS";
}
// delete application
Dao class
#Override
public void deleteById(Long id) {
Application application = findById(id);
em.remove(application);
}
Thank you in advance.
After a while i'm able to find a solution of my question which is,
ApplicationControllerTest.class
package com.spring.addapplication.test.controller;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.spring.addapplication.controller.ApplicationController;
import com.spring.addapplication.model.Application;
import com.spring.addapplication.service.ApplicationService;
import com.spring.addapplication.url.UrlChecker;
#RunWith(SpringJUnit4ClassRunner.class)
public class ApplicationControllerTest {
#Mock
ApplicationService applicationService;
private MockMvc mockMvc;
#Before
public void setUp() throws Exception {
initMocks(this);// this is needed for inititalization of mocks, if you use #Mock
ApplicationController controller = new ApplicationController(applicationService,urlChecker);
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
#Test
public void deleteApplication() throws Exception {
Mockito.when(applicationService.removeById(10001L)).thenReturn("SUCCESS");
mockMvc.perform(MockMvcRequestBuilders.delete("/applications", 10001L))
.andExpect(status().isOk());
}
I have a class where I'm using Powermock + Mockito to suppress a static method in a utility class. It works fine with Powermock 1.6.2 and Mockito 1.10.19, but I've been tasked with moving to Java 10 (JRE: we're still compiling with Java 8) and so I've moved to Powermock 2 (currently in beta) and Mockito 2.16.1. Now, I consistently get org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here.
A simple example, MyMockito.java:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.lang.reflect.Method;
import static org.mockito.Mockito.any;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.support.membermodification.MemberMatcher.method;
import static org.powermock.api.support.membermodification.MemberModifier.suppress;
#RunWith(PowerMockRunner.class)
#PrepareForTest(StringMeasurer.class)
public class MyMockito {
#Test
public void testSuppressMethod() throws Exception {
spy(StringMeasurer.class);
Method measure = method(StringMeasurer.class, "measure", String.class);
suppress(measure);
when(StringMeasurer.class, measure)
.withArguments(any(String.class))
.thenReturn(10);
System.out.println(StringMeasurer.measure("Hello"));
}
And StringMeasurer.java:
public class StringMeasurer {
private StringMeasurer() {}
public static int measure(String s) {
return s.length();
}
}
}
I'm assuming that either there have been some changes to how matchers can be used to match arguments in stubbed static methods, or else this should never have worked and somehow got through in Mockito 2 (or possibly this is a bug in the Powermock beta). Can anyone provide me some insight into what I'm doing wrong?
Working solution for PowerMock 2.0.0-beta.5:
import static org.mockito.ArgumentMatchers.any;
import static org.powermock.api.mockito.PowerMockito.when;
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(StringMeasurer.class)
public class MyMockito {
#Test
public void testSuppressMethod() throws Exception {
PowerMockito.mockStatic(StringMeasurer.class);
when(StringMeasurer.measure(any(String.class))).thenReturn(10);
System.out.println(StringMeasurer.measure("Hello"));
}
}
More details can be found in the official PowerMock documentation: Mocking Static Method
The question uses the PowerMockito.spy() method, which is required for partial mocking, although the example given only has one static method, so that's not necessary here. Here's a working solution that uses partial mocking for an extended example:
MyMockito.java:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.lang.reflect.Method;
import java.util.List;
import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.*;
import static org.powermock.api.support.membermodification.MemberMatcher.method;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.spy;
#RunWith(PowerMockRunner.class)
#PrepareForTest(StringMeasurer.class)
public class MyMockito {
#Test
public void testSuppressMethod() throws Exception {
spy(StringMeasurer.class);
Method measure = method(StringMeasurer.class, "measure", String.class);
doReturn(10).when(StringMeasurer.class, measure)
.withArguments(any(String.class));
System.out.println(StringMeasurer.measure("Hello"));
List<String> dummy = StringMeasurer.dummy(5);
assertEquals(5, dummy.size());
dummy.forEach(System.out::println);
}
}
And StringMeasurer.java:
import java.util.ArrayList;
import java.util.List;
public class StringMeasurer {
private StringMeasurer() {}
public static int measure(String s) {
return s.length();
}
public static List<String> dummy(int size) {
List<String> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
list.add("" + i);
}
return list;
}
}
Note that, in this case, the accepted solution would mock the StringMeasurer.dummy() method as well, returning an empty list, and the test would fail on the assertEquals().