I have a service project written in Java11. It is using junit tests to cover full code coverage.
I have written scheduler method to updateFiles (invoked by Files.walkFileTree) in FileReceivingStateMarkerService class. I want to test static call Files.walkFileTree from test class written for FileReceivingStateMarkerService. I need to use PowerMockRunner to test static call as it cannot be tested by simple MockitoJunitRunner.
On running test, I am getting NPE in setUp method at line - mockStatic(Files.class);
Can you please help me to resolve issue on how to configure powermock with Java11 and initialize static class?
I configured powermock in service project (in Java11) as below
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.0-RC.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.0-RC.1</version>
<scope>test</scope>
</dependency>
FileReceivingStateMarkerService class
class FileReceivingStateMarkerService {
private static final Logger LOG = LoggerFactory.getLogger(FileReceivingStateMarkerService.class);
private final FileProcessingActivityRepositoryService fileProcessingActivityRepositoryService;
private final FilePollActivityRepository filePollActivityRepository;
private final FileProcessingRequestRepositoryService fileProcessingRequestRepositoryService;
#Autowired
FileReceivingStateMarkerService(FileProcessingActivityRepositoryService fileProcessingActivityRepositoryService, FilePollActivityRepository filePollActivityRepository,
FileProcessingRequestRepositoryService fileProcessingRequestRepositoryService) {
this.fileProcessingActivityRepositoryService = fileProcessingActivityRepositoryService;
this.filePollActivityRepository = filePollActivityRepository;
this.fileProcessingRequestRepositoryService = fileProcessingRequestRepositoryService;
}
#Scheduled(fixedDelayString="#{${fileprocess.filemonitor.interval.minutes}*60*1000}")
void updateFiles() {
List<FileProcessingRequest> requests = fileProcessingRequestRepositoryService.getFileProcessingRequests();
LOG.debug("Running file receiving state");
requests.forEach(request -> {
LOG.debug("Looking at location {}", request.getFileLocation());
final var fileVisitor = new FileReceivingStateMarkerFileVisitor(filePollActivityRepository
, fileProcessingActivityRepositoryService
, request);
try {
Files.walkFileTree(Path.of(request.getFileLocation()), Collections.emptySet(), 1, fileVisitor);
} catch(Exception e) {
LOG.debug(e.getMessage());
}
});
}
}
Test class for FileReceivingStateMarkerService
package com.experianhealth.rfp.scheduler;
import com.experianhealth.rfp.core.DocumentType;
import com.experianhealth.rfp.core.FileProcessingRequest;
import com.experianhealth.rfp.dao.FilePollActivityRepository;
import com.experianhealth.rfp.service.FileProcessingActivityRepositoryService;
import com.experianhealth.rfp.service.FileProcessingRequestRepositoryService;
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.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.mockito.ArgumentMatchers.any;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
#RunWith(PowerMockRunner.class)
#PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"})
#PrepareForTest(FileReceivingStateMarkerService.class)
public class FileReceivingStateMarkerServicePowerTest {
#Mock
private FileProcessingActivityRepositoryService fileProcessingActivityRepositoryService;
#Mock
private FilePollActivityRepository filePollActivityRepository;
#Mock
private FileProcessingRequestRepositoryService fileProcessingRequestRepositoryService;
#Before
public void setUp() throws Exception {
mockStatic(Files.class);
}
#Test
public void updateFiles() throws Exception {
String rootDir = "C:\\files_processor";
List<FileProcessingRequest> requests = new ArrayList<>();
FileProcessingRequest request = new FileProcessingRequest();
request.setClientId("123");
request.setTradingPartnerId("123");
request.setDocumentId(DocumentType.Payer);
request.setFileLocation(rootDir);
requests.add(request);
final var fileVisitor = new FileReceivingStateMarkerFileVisitor(filePollActivityRepository
, fileProcessingActivityRepositoryService
, request);
try {
PowerMockito.when(Files.walkFileTree(Path.of(request.getFileLocation() ), Collections.emptySet(), 1, fileVisitor))
.thenReturn(any());
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
Related
I want to write the Unit test using PowerMockito/Mockito for my static method/void method.
But When I try to run , I got the following error:
/Users/<username>/Library/Java/JavaVirtualMachines/corretto-
---- IntelliJ IDEA coverage runner ----
sampling ...
include patterns:
exclude patterns:
ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider jdk.nashorn.api.scripting.NashornScriptEngineFactory not a subtype
ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider jdk.nashorn.api.scripting.NashornScriptEngineFactory not a subtype
java.lang.NoSuchMethodError: org.mockito.MockingDetails.getMockHandler()Lorg/mockito/invocation/MockHandler;
at org.powermock.api.mockito.invocation.MockHandlerAdaptor.getMockHandler(MockHandlerAdaptor.java:56)
at org.powermock.api.mockito.invocation.MockHandlerAdaptor.createInvocation(MockHandlerAdaptor.java:81)
at org.powermock.api.mockito.invocation.MockHandlerAdaptor.performIntercept(MockHandlerAdaptor.java:61)
at org.powermock.api.mockito.invocation.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:93)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:186)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:168)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:138)
I am new to use powerMockito/Mockito, Can Anyone help to figure out the exact issue.
This is my CreateTaskBuilder Class method that I want to test:
Here JgitAccessor.clone() is a static void methid that I used donothing() for it.
public void Repository() throws DependencyFailureException, IOException, GitAPIException {
try {
ServiceAccessor.loadTmpSshTicket();
if (!Files.exists(Paths.get(LambdaEnv.GIT_SSH_SCRIPT.getValue()))) { // getValue will throw exception on null
throw new IllegalStateException(String.format("Environment variable GIT_SSH points to file %s but it doesn't exist.",
LambdaEnv.GIT_SSH_SCRIPT.getValue()));
}
JgitAccessor.clone(REPO_URI, CLONED_REPO_PATH);
} catch (IOException | DependencyFailureException e) {
log.info("Exception occurred while performing Service client integration. exception: [{}]", e.getMessage());
e.printStackTrace();
}
}
And this is the unit test class :
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
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 java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.mockito.Mockito.*;
#RunWith(PowerMockRunner.class)
#PowerMockIgnore({"javax.management.*"})
#PrepareForTest({CreateTaskBuilder.class, LambdaEnv.class, ServiceAccessor.class, JgitAccessor.class})
public class CreateTaskBuilderTest extends TestUtils {
#Mock
private ServiceAccessor serviceAccessor;
#Mock
private JgitAccessor jgitAccessor;
#InjectMocks
CreateTaskBuilder builder;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void loadServiceTicket_happyCase() throws Exception {
doNothing().when(serviceAccessor).loadTmpSshTicket();
PowerMockito.mockStatic(System.class);
Mockito.when(System.getenv("GIT_SSH")).thenReturn("/tmp/ssh.sh");
PowerMockito.mockStatic(Files.class);
Mockito.when(Files.exists(Paths.get("/tmp/ssh.sh"))).thenReturn(true);
PowerMockito.mockStatic(JgitAccessor.class);
PowerMockito.doNothing().when(JgitAccessor.class, "clone", Mockito.anyString(), Mockito.anyString());
builder.cloneRepository();
}
I am using Mockito = 2.28.x; PowerMockMockito = 2.x;
It looks like you have the wrong versions of libraries on your classpath.
The version of PowerMock you are using requires a Mockito with an org.mockito.MockingDetails.getMockHandler() which is not available in Mocktio 2.8.x. You can find it in a later version in 2.23.x.
Looking at minimum version dependencies for powermock-api-mockito2 version 2.0.0 you should be using mockito version 2.23.0 or later.
So looks like you need to update Mockito to a later version compatible with your PowerMock version, 2.23.x or later instead of 2.8.x.
Here is the method for which I need to write the Junit test case.
Problem is here to write JUnit test cases for the following method which return the future
public Future<SomeResponse> getSomeResponse(SomeQuery someQuery){
if(dbCircuitBreaker == null){
dbCircuitBreaker= CircuitBreakers.getDbCircuitBreaker();
}
return dbCircuitBreaker.execute(future -> {
List<SomeResponseMetaData> SomeResponseMetaDataList = new ArrayList<>();
SomeResponse someResponse = new SomeResponse();
Observable<Some> someMetaDataObservable = someSQLRepository.findSomeDetails(someQuery);
someMetaDataObservable.subscribe(some -> {
getSomeResponse(someResponseMetaDataList,some);
},throwable -> {
FIDAL_LOGGER.error(CLASS_FULL_NAME, "getSomeResponse", LogConstants.UNCAUGHT_ERROR, "Could not able to fetch the data from some", throwable);
},()->{
FIDAL_LOGGER.info(CLASS_FULL_NAME, "getSomeResponse", LogConstants.UNCAUGHT_ERROR, "fetch the data for some is completed");
someResponse.setSomeLists(someResponseMetaDataList);
future.complete(someResponse);
});
});
}
This the not the best solution but I have written which is working fine for me.
import io.vertx.rxjava.circuitbreaker.CircuitBreaker;
import io.vertx.rxjava.core.Future;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.PowerMockRunner;
import rx.Single;
import rx.observers.TestSubscriber;
import java.util.ArrayList;
import java.util.List;
#RunWith(PowerMockRunner.class)
#PowerMockIgnore("javax.management.*")
public class FileServiceHelperTest {
#Mock
SomeServiceHelper someServiceHelper = null;
#InjectMocks
CircuitBreaker dbCircuitBreaker = null;
#InjectMocks
SomeLineSQLRepository someLineSQLRepository = null;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void getSomeResponse() {
SomeResponseMetaData someResponseMetaData = new SomeResponseMetaData();
someResponseMetaData.setRecievedDate("2020-02-12T03:57:01-0600");
someResponseMetaData.setFileName("29579_3_Order_File1_20200207050043852");
someResponseMetaData.setSomeId("43b61ab4-52b8-48e6-9489-b5824d278254");
someResponseMetaData.setSomeStatus("PROCESSED");
someResponseMetaData.setSubmitted("3");
someResponseMetaData.setProcessed("0");
someResponseMetaData.setPending("0");
someResponseMetaData.setErrors("3");
someResponseMetaData.setSomeType("ORDER");
someResponseMetaData.setShipNodeId("29579_3");
List<SomeResponseMetaData> someResponseMetaDataList = new ArrayList();
someResponseMetaDataList.add(someResponseMetaData);
SomeResponse someResponseExpected = new SomeResponse();
someResponseExpected.setSomeLists(someResponseMetaDataList);
Future<SomeResponse> someResponseFuture = Future.succeededFuture(someResponseExpected);
SomeQuery someQuery = new SomeQuery.SomeQueryBuilder("29579").setPageNo(0).setPageSize(1).build();
Mockito.when(someServiceHelper.getSomeResponse(someQuery)).thenReturn(someResponseFuture);
Single<SomeResponse> someResponseSingle = someServiceHelper.getSomeResponse(someQuery).rxSetHandler();
TestSubscriber<SomeResponse> testSubscriber = new TestSubscriber();
someResponseSingle.subscribe(testSubscriber);
testSubscriber.assertCompleted();
testSubscriber.assertNoErrors();
testSubscriber.assertValue(someResponseExpected);
}
}
Since i am new to Mockito and AEM model java. I have a gone through some docs and wrote my first Mockito file for AEM Model java. In my code i've not see any errors, but while running i am not getting success and can't complete the code coverage 100%. Can anyone correct/help me to fix my code[given sample java with respective mockito file]
Java File:
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.abc.cc.ddd.ResourceResolverService;
import com.abc.cc.ddd.services.models.bean.Accordion;
#Model(adaptables = SlingHttpServletRequest.class)
public class AccordionModel {
private final static Logger log = LoggerFactory.getLogger(AccordionModel.class);
#SlingObject
private SlingHttpServletRequest request;
#Inject
public ResourceResolverService resolverService;
private Resource resource;
public List < Accordion > accordionList = new ArrayList < Accordion > ();
#PostConstruct
protected void init() throws LoginException, JSONException {
log.info("AccordionModel init method Start");
resource = request.getResource();
final ValueMap configurationOptionProperties = resource.getValueMap();
log.debug("iconfigurationOptionProperties is " + configurationOptionProperties);
String count = configurationOptionProperties.get("count", String.class);
if (count != null) {
for (int i = 1; i <= Integer.valueOf(count); i++) {
Accordion accordion = new Accordion();
String title = configurationOptionProperties.get("title" + i, String.class);
String rte = configurationOptionProperties.get("rte" + i, String.class);
accordion.setTitle(title);
accordion.setRte(rte);
accordionList.add(accordion);
}
}
log.info("AccordionModel init method End");
}
public List < Accordion > getAccordionList() {
return accordionList;
}
}
Mockito code
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.json.JSONException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import com.abc.cc.ddd.ResourceResolverService;
import com.abc.cc.ddd.services.models.bean.Accordion;
#RunWith(MockitoJUnitRunner.class)
public class AccordionModelTest {
#InjectMocks
private AccordionModel accordionModel;
#Mock
Resource resource;
#Mock
SlingHttpServletRequest request;
#Mock
ResourceResolverService resourceResolverService;
#Mock
ValueMap valuemap;
public List < Accordion > accordionList = new ArrayList < Accordion > ();
String count = "6";
//max count, based on this count loop execute and get/set into the list
#Before
public void setUp() throws Exception {
when(request.getResource()).thenReturn(resource);
when(resource.getValueMap()).thenReturn(valuemap);
}
#Test
public void shouldReturnNullWhenPropertyIsNull() throws LoginException, JSONException {
when(valuemap.get("count", String.class)).thenReturn(null);
accordionModel.init();
assertEquals(accordionModel.getAccordionList(), null);
}
#Test
public void shouldReturnWhenPropertyNotNull() throws LoginException, JSONException {
when(valuemap.get("count", String.class)).thenReturn("count");
accordionModel.init();
assertEquals(accordionModel.getAccordionList(), count);
}
}
Errors in program its showing line--> accordionModel.init();
java.lang.NumberFormatException: For input string: "count"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.valueOf(Unknown Source)
at com..services.sling.models.AccordionModel.init(AccordionModel.java:44) at
com..services.sling.models.AccordionModelTest.
shouldReturnWhenPropertyNotNull(AccordionModelTest.java:55)
java.lang.AssertionError: expected:<[]> but was:<null>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:144)
at com..services.sling.models.AccordionModelTest.
shouldReturnNullWhenPropertyIsNull(AccordionModelTest.java:53)
java.lang.AssertionError: expected:<[]> but was:<null>
If you return null your list is empty. So adjust your test.
Consider renaming the method name as well.
If thats not what you want, you'll need to change your implementation.
#Test
public void shouldReturnNullWhenPropertyIsNull() throws LoginException, JSONException {
when(valuemap.get("count", String.class)).thenReturn(null);
accordionModel.init();
assertTrue(accordionModel.getAccordionList().isEmpty());
}
java.lang.NumberFormatException: For input string: "count"
"count" can not be converted into an Integer. Try using your count variable ("6") instead.
You should check the content of the list, for now I adjusted it to check that the list has the correct size.
#Test
public void shouldReturnWhenPropertyNotNull() throws LoginException, JSONException {
when(valuemap.get("count", String.class)).thenReturn(count);
accordionModel.init();
assertEquals(Integer.valueOf(count), accordionModel.getAccordionList().size());
}
Note that generally the parameter order for assert's should be expected vs actual.
This is the new file I've added in addition to the existing Persistenceconfig.Java. I'm getting this entity manager as 2 found.
we're not using any xml config except for the jpa repositories in spring-data.xml
The issues is occuring only for one package created newly for logging activity and that is also included in jpa repository.
Before adding the below class, everything is normal previously
package com.jumbotree.kumcha.config;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
//import org.springframework.orm.hibernate5.HibernateExceptionTranslator;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
//#PropertySource("classpath:kumcha.properties")
#PropertySource("file:/opt/jumbotree/kumcha2/kms.properties")
#EnableJpaRepositories(basePackages = "com.jumbotree.kumcha.crm.model", entityManagerFactoryRef = "createEntityManagerFactoryChargingBean", transactionManagerRef = "createChargingTransactionManagerBean")
#ImportResource("classpath:spring-data.xml")
public class ChargingPersistenceConfig {
#Autowired
private Environment env;
private static final Logger LOGGER = LoggerFactory.getLogger(ChargingPersistenceConfig.class);
#Bean
public DataSource createChargingDataSourceBean() {
LOGGER.info("Charging Datasource created...");
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("charging.db.driver"));
dataSource.setUrl(env.getProperty("charging.db.url"));
dataSource.setUsername(env.getProperty("charging.db.username"));
dataSource.setPassword(env.getProperty("charging.db.password"));
return dataSource;
}
//Here is the entity manager added and causing this issue
#Bean //(name = "entityManagerFactoryCharging")
#PersistenceContext (unitName="chargingPU")
public FactoryBean<EntityManagerFactory> createChargingEntityManagerFactoryBean(#Qualifier("createChargingDataSourceBean") DataSource dsc) {
LocalContainerEntityManagerFactoryBean chargingentityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
LOGGER.info("Charging entityman created...");
try {
chargingentityManagerFactoryBean.setDataSource(createChargingDataSourceBean());
chargingentityManagerFactoryBean.setPackagesToScan("com.jumbotree.kumcha.crm.model");
chargingentityManagerFactoryBean.setJpaVendorAdapter(createJpaVendorAdapterBean());
chargingentityManagerFactoryBean.setJpaProperties(createJpaProperties());
} catch (Exception e) {
// TODO: handle exception
LOGGER.error(e.toString());
}
return chargingentityManagerFactoryBean;
}
private Properties createJpaProperties() {
LOGGER.info("hibernate.show_sql :::: "+env.getProperty("hibernate.show_sql"));
return new Properties() {
{
// setProperty("hibernate.hbm2ddl.auto", "create-drop");
setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
setProperty("hibernate.format_sql", env.getProperty("hibernate.format_sql"));
// setProperty("hibernate.cache.use_second_level_cache", "true");
// setProperty("hibernate.cache.provider_class", "org.hibernate.cache.EhCacheProvider");
// setProperty("shared-cache-mode", "DISABLE_SELECTIVE");
//<property name="hibernate.cache.use_second_level_cache" value="true"/>
//setProperty("hibernate.connection.zeroDateTimeBehavior", "convertToNull");
}
};
}
private JpaVendorAdapter createJpaVendorAdapterBean() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
// jpaVendorAdapter.setDatabase(Database.valueOf(env.getProperty("db.name")));
jpaVendorAdapter.setShowSql(true);
// jpaVendorAdapter.setGenerateDdl(true);
jpaVendorAdapter.setDatabasePlatform(env.getProperty("hibernate.dialect"));
return jpaVendorAdapter;
}
#Bean //(name = "transactionManager")
public PlatformTransactionManager createChargingTransactionManagerBean() throws Exception {
LOGGER.info("Charging transactionMan created...");
JpaTransactionManager chargingtransactionManager = new JpaTransactionManager();
chargingtransactionManager.setEntityManagerFactory(createChargingEntityManagerFactoryBean(createChargingDataSourceBean()).getObject());
return chargingtransactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor createPersistenceExceptionTranslationPostProcessor() {
return new PersistenceExceptionTranslationPostProcessor();
}
// Required if using Hibernate 4
#Bean
public PersistenceExceptionTranslator createPersistenceExceptionTranslatorBeaan() {
return new HibernateExceptionTranslator();
}
}
LoggerRepository cannot choose one of the 2 beans createChargingEntityManagerFactoryBean and createEntityManagerFactoryBean
Make one of them primary and/or specify qualifier. (BTW sometimes even with qualifier it's necessary to make one of beans primary)
Cannot suggest cconfig changes without your code.
I am getting a result from my unit test that I don't quite understand.
Controller Code
package com.rk.capstone.controllers;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.rk.capstone.model.domain.User;
import com.rk.capstone.model.services.user.IUserService;
/**
* REST Controller for /register endpoint
*/
#RestController
#RequestMapping("/register")
public class RegisterController {
private final IUserService userService;
public RegisterController(IUserService userService) {
this.userService = userService;
}
#RequestMapping(value = "/user", method = RequestMethod.POST)
public ResponseEntity<User> registerNewUser(#RequestBody User user) {
if (userService.findByUserName(user.getUserName()) == null) {
user = userService.saveUser(user);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
} else {
return ResponseEntity.status(HttpStatus.CONFLICT).body(null);
}
}
}
Unit Test Code:
package com.rk.capstone.controllers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rk.capstone.model.dao.UserDao;
import com.rk.capstone.model.domain.User;
import com.rk.capstone.model.services.user.IUserService;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Class Provides Unit Testing for RegisterController
*/
#RunWith(SpringRunner.class)
#WebMvcTest(RegisterController.class)
public class RegisterControllerTest {
#MockBean
private IUserService userService;
#Autowired
private MockMvc mockMvc;
private User user;
private String userJson;
#Before
public void setup() {
user = new User("rick", "k", "rick#email.com", "rkow", "abc123");
ObjectMapper objectMapper = new ObjectMapper();
try {
userJson = objectMapper.writeValueAsString(user);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
#Test
public void testRegisterNewUserPostResponse() throws Exception {
given(this.userService.findByUserName(user.getUserName())).willReturn(null);
given(this.userService.saveUser(user)).willReturn(user);
Assert.assertNotNull("Mocked UserService is Null", this.userService);
this.mockMvc.perform(post("/register/user").content(userJson).
contentType(MediaType.APPLICATION_JSON)).
andExpect(status().isCreated()).
andDo(print()).andReturn();
}
}
The result of the print() is below, I do not understand why the Body is empty. I have tried numerous things I've read on other posts and blogs and no matter what I try the Body is always empty. Adding a Content-Type header in the controller response makes no difference.
MockHttpServletResponse:
Status = 201
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
What is confounding me even more, is when I run the actual application and perform a POST using PostMan to the /register/user endpoint the response contains the body and status code I expect, a User represented via JSON, e.g.
Status Code: 201 Created
Response Body
{
"userId": 1,
"firstName": "rick",
"lastName": "k",
"emailAddress": "rick#email.com",
"userName": "rk",
"password": "abc123"
}
Any help or ideas is appreciated, using SpringBoot 1.4.0.RELEASE.
UPDATE: For some reason the following mocked method call is returning null in the controller under test.
given(this.userService.saveUser(user)).willReturn(user);
This thread ultimately turned me on to a solution:
Mockito when/then not returning expected value
Changed this line:
given(this.userService.saveUser(user)).willReturn(user);
to
given(this.userService.saveUser(any(User.class))).willReturn(user);