How to Mock ReloadableResourceBundleMessageSource in this case - spring

I have a Rest controller class as shown below
#RestController
public class MyController {
#Autowired
private MYHelper myHelper;
#Autowired
#Qualifier("environmentMessageSource")
protected ReloadableResourceBundleMessageSource environmentMessageSource;
#PostMapping(value = {
employees
})
public #ResponseBody Map < String, Object > getEmployees(#RequestBody MyVO myvo) throws Exception {
Map < String, Object > responseMap = new HashMap < > ();
try {
responseMap = oeHelper.getDataService(environmentMessageSource.getMessage("MYPROP", null, null), myvo);
} catch (Exception e) {
}
return responseMap;
}
}
I am trying to write a Test Case for my controller . and its failing at ReloadableResourceBundleMessageSource
#RunWith(MockitoJUnitRunner.class)
public class MyControllerTest {
private MockMvc mockMvc;
#Mock
private OEHelper myHelper;
#InjectMocks
private MyController myController;
#Mock
protected ReloadableResourceBundleMessageSource environmentMessageSource;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders
.standaloneSetup(myController)
.build();
environmentMessageSource.setCacheSeconds(0);
}
#Test
public void testgetESIDAndCalendarDates() throws Exception {
Map < String, Object > responseMap = new HashMap < > ();
MyVO myVO = new MyVO();
Mockito.when(messageSource.getMessage(Mockito.anyString(), Mockito.any(Object[].class), Mockito.any(Locale.class)))
.thenReturn("");
Mockito
.when(myHelper.getResponseFromService(Mockito.any(), Mockito.any(myVO.class)))
.thenReturn(responseMap);
mockMvc.perform(post("/employees")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(myVO))
)
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
Its saying , it cannot find the key MYPROP in environpropertiesfile for locale null
org.springframework.context.NoSuchMessageException: No message found under code 'MYPROP' for locale 'null'.

Related

I get always that java.lang.AssertionError: Status expected:<200> but was:<404>

i added a mocked user this my class
#TestConfiguration
public class UserDetailsMock {
final String apiAccessGroup = "00000000-0000-0000-0000-000000000000";
#Bean
#Primary
public UserDetailsService userDetailsService() {
User ericssonUser = new User("ericsson-worker", "secret", Arrays.asList());
User msApiUser = new User("msApiUser", "StrongPass", Arrays.asList(new SimpleGrantedAuthority(apiAccessGroup)));
return new InMemoryUserDetailsManager(Arrays.asList(
ericssonUser, msApiUser
));
}
}
and this my test Class any help please!!!!
#SpringBootTest(
classes = UserDetailsMock.class
)
#AutoConfigureMockMvc
public class MuninServiceAuthorizationTest {
#Autowired
MockMvc mockMvc;
List<MockHttpServletRequestBuilder> endpoints;
#BeforeEach
public void setUp() throws IOException {
MockitoAnnotations.openMocks(this);
endpoints = Arrays.asList(
MockMvcRequestBuilders.post("/migrate/foss").with(csrf()),
MockMvcRequestBuilders.get("/swagger/ui/**"));
}
#Test
#WithUserDetails("msApiUser")
void userWithGroupWhichIsAllowedToUseApiShouldGet200() throws Exception {
for (MockHttpServletRequestBuilder mockHttpServletRequestBuilder : endpoints) {
mockMvc.perform(mockHttpServletRequestBuilder)
.andExpect(status().isOk());
}
}
}

MockMvc response returns 404, expected response 201

I am new to unit testing REST API in Spring Boot.
I am expecting response status as CREATED but instead I am getting a PAGE NOT FOUND error.
Below is the code for:-
UserControllerUnitTests
#SpringBootTest
#ContextConfiguration(classes = { CommonConfig.class, SecurityConfig.class})
#RunWith(SpringRunner.class)
class UserControllerUnitTests {
private static ObjectMapper mapper;
private static final String URI = "/users";
MockMvc mvc;
#Autowired
WebApplicationContext webAppContext;
#Mock
UserService userService;
MvcResult mvcResult;
#BeforeAll
static void setUp() {
mapper = new ObjectMapper();
}
#BeforeEach
void initialize() throws Exception {
mvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();
....
....
....
void shouldReturnStatusCreatedIfValidUserPassedForPostUser(long index) throws Exception {
int expectedStatus = HttpStatus.CREATED.value();
UserDAO returnUser;
UserDAO user = userList.get(index);
userList.remove(index);
String jsonContent = mapper.writeValueAsString(user);
user.setId(index);
user.setEncryptedPassword(null);
Mockito.when(userService.addUser(Mockito.any())).thenReturn(user);
mvcResult = mvc.perform(MockMvcRequestBuilders.post(URI)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonContent)).andReturn();
//Mockito.verify(userService, Mockito.times(1)).addUser(Mockito.any());
int actualStatus = mvcResult.getResponse().getStatus();
Assert.assertEquals("Response status should be CREATED", expectedStatus, actualStatus);
jsonContent = mvcResult.getResponse().getContentAsString();
returnUser = mapper.readValue(jsonContent, UserDAO.class);
Assert.assertEquals("EncryptedPassword should not be returned", null,
returnUser.getEncryptedPassword());
}
User Controller.class
#RestController
#RequestMapping("users/")
public class UserController {
UserService userService;
#Autowired
public UserController(UserService userService) {
this.userService = userService;
}
....
....
....
#PostMapping(path = "",
consumes = { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON },
produces = { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public ResponseEntity<UserDAO> createUser(#Valid #RequestBody UserDAO user) {
String password = user.getEncryptedPassword();
user.setEncryptedPassword(null);
UserDAO retreivedUser;
if(user.getId() != 0)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
user.setEncryptedPassword(password);
retreivedUser = userService.addUser(user);
if(retreivedUser != null)
return new ResponseEntity<>(retreivedUser, HttpStatus.CREATED);
return new ResponseEntity<>(HttpStatus.CONFLICT);
}
}
The full code can be found at https://github.com/vineethmaller/springboot-userservice
I spotted a few errors:
Get rid of ContextConfiguration
#SpringBootTest
// #ContextConfiguration(classes = { CommonConfig.class, SecurityConfig.class})
#RunWith(SpringRunner.class)
class UserControllerUnitTests {
Specify correct mapping on the controller (no slash)
#RestController
#RequestMapping("users")
public class UserController {
You setup your UserService mock which is not used in the test. Did you mean #MockBean?
#MockBean
UserService userService;

Writing a test to Spring boot REST API that retrieve data from a DB

I have a spring boot REST API with a GET method that returns data available in a DB. I am attempting to write an integration test to test this API method. I have configured the test to use the H2 database. I am trying to add some mock data to the database before the test is executed and see if the API retrieves that data. Following is the code I have written so far.
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
#TestPropertySource(locations = "classpath:application-test.properties")
public class MetaControllerTest {
#Autowired
private MockMvc mvc;
#Autowired
private ProvinceDAO provinceDAO;
#Transactional
#Before
public void addData () {
Province southern = getProvinceEntity("Southern", "දකුණ", "தென்");
provinceDAO.createEntity(southern);
System.out.println(provinceDAO.findAll(Province.class).size());
}
#Test
public void testGetProvinces() throws Exception {
MvcResult result = mvc.perform(get("/meta/provinces"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andReturn();
System.out.println(result.getResponse().getContentAsString());
}
}
However, when I run this code, I am getting an error saying "org.springframework.dao.InvalidDataAccessApiUsageException: No transactional EntityManager available; nested exception is java.lang.IllegalStateException: No transactional EntityManager available"
I have also attempted using #MockBean instead of #Autowired to bind the provinceDAO. Even though this prevents the error, it does not persist the entity in the database.
How should I write my testcase to test my method here?
Update:
application-test.properties
spring.datasource.url = jdbc:h2:mem:test
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
Entity -> Province.java
#Entity
#Table(name = "w4a_province")
public class Province {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int id;
#Column(name = "province_name")
private String name;
#Column(name = "province_name_si")
private String nameSi;
#Column(name = "province_name_ta")
private String nameTa;
.
.
}
GenericDAO.java
#Repository
public class GenericDAO<T> implements IGenericDAO<T> {
#PersistenceContext
private EntityManager em;
#Override
public Session getCurrentSession() {
return this.em.unwrap(Session.class);
}
#Override
public T findByPrimaryKey(Class<T> clazz, Object primaryKey) {
return getCurrentSession().find(clazz, primaryKey);
}
#Override
public List<T> findAll(Class<T> clazz) {
DetachedCriteria criteria = DetachedCriteria.forClass(clazz);
return criteria.getExecutableCriteria(getCurrentSession()).list();
}
#Override
public T createEntity(T entity) {
getCurrentSession().save(entity);
return entity;
}
ProvinceDAOImpl.java
#Repository
public class ProvinceDAOImpl extends GenericDAO<Province> implements ProvinceDAO {
}
MetaController.java
#RestController
#PreAuthorize("permitAll()")
public class MetaController {
private final MetaService metaService;
#Autowired
public MetaController(MetaService metService) {
this.metaService = metService;
}
#GetMapping("/meta/provinces")
public ResponseEntity<List<ProvinceDTO>> getProvinces() {
if (logger.isDebugEnabled()) {
logger.debug("Retrieving list of provinces.");
}
List<ProvinceDTO> provinces = metaService.getProvinces();
return ResponseEntity.ok(provinces);
}
}
MetaServiceImpl.java
#Service
#Transactional
public class MetaServiceImpl implements MetaService {
private final ProvinceDAO provinceDAO;
#Autowired
public MetaServiceImpl(ProvinceDAO provnceDAO) {
this.provinceDAO = provnceDAO;
}
public List<ProvinceDTO> getProvinces() {
if (logger.isDebugEnabled()) {
logger.debug("Obtaining a list of provinces from database.");
}
List<Province> entities = provinceDAO.findAll(Province.class);
if (logger.isDebugEnabled()) {
logger.debug("Converting province entities to dtos.");
}
List<ProvinceDTO> dtos = new ArrayList<>();
for (int i = 0; i < entities.size(); i++) {
Province entity = entities.get(i);
if (LocaleContextHolder.getLocale().getLanguage().equals(
GlobalConstants.LanguageIdentifiers.SINHALA_LANGUAGE_TAG)) {
dtos.add(new ProvinceDTO(entity.getId(), entity.getNameSi()));
} else if (LocaleContextHolder.getLocale().getLanguage().equals(
GlobalConstants.LanguageIdentifiers.TAMIL_LANGUAGE_TAG)) {
dtos.add(new ProvinceDTO(entity.getId(), entity.getNameTa()));
} else {
dtos.add(new ProvinceDTO(entity.getId(), entity.getName()));
}
}
return dtos;
}
}
I managed to feed the database with the required data by placing a SQL script data-h2.sql with insert queries at the test/resources folder. This prevented the requirement to use an EntityManager or a DAO.
Furthermore, I added the following property to the application-test.properties file.
spring.datasource.platform=h2
In Order to test Rest Api You can try functional test as well as integration test.
You can prepare your own response formate as required and check whether the same is returned or else you can also verify whether the data from db is fine or not.Plz check the below example
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = FactsMain.class)
#WebAppConfiguration
public abstract class BaseTest {
protected MockMvc mvc;
#Autowired
WebApplicationContext webApplicationContext;
protected void setUp() {
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
protected String mapToJson(Object obj) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(obj);
}
protected <T> T mapFromJson(String json, Class<T> clazz)
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json, clazz);
}
}
In First test case i am forming the response format and trying to return the same and then validating the same.Here i don't need the db data so i have kept service as mock instead of auto wired.And used ObjectMapper for converting json to java and then java obj to json from base Test class.
public class PersonalDetailsControllerTest extends BaseTest {
#MockBean
private IPersonalService service;
private static final String URI = "/api/personalDetails";
#Override
#Before
public void setUp() {
super.setUp();
}
#Test
public void testGet() throws Exception {
PersonalDetailsEntity entity = new PersonalDetailsEntity();
List<PersonalDetailsEntity> dataList = new ArrayList<PersonalDetailsEntity>();
FactsAdminResponse<PersonalDetailsEntity> dataResponse = new FactsAdminResponse<PersonalDetailsEntity>();
entity.setId(1);
entity.setName(“Anthony Holmes”);
entity.setAge(26);
entity.setCity(“Banglore”);
entity.setCountry(“India”);
dataList.add(entity);
dataResponse.setData(dataList);
Mockito.when(service.getBuildings()).thenReturn(dataList);
RequestBuilder requestBuilder = MockMvcRequestBuilders.get(URI)
.accept(MediaType.APPLICATION_JSON);
MvcResult mvcResult = mvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
String expectedJson = this.mapToJson(dataResponse);
String outputInJson = mvcResult.getResponse().getContentAsString();
assertEquals(HttpStatus.OK.value(), response.getStatus());
assertEquals(expectedJson, outputInJson);
}
}
In below case we are getting the actual data in json format as we are doing rest api call and then just validating the status apart from status you can also cross check the data
public class PersonalDetailsControllerTest extends BaseTest {
private static final String URI = "/api/personalDetails";
#Override
#Before
public void setUp() {
super.setUp();
}
#Test
public void getGet() throws Exception {
MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(URL)
.accept(MediaType.APPLICATION_JSON_VALUE)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(200, status);
String content = mvcResult.getResponse().getContentAsString();
//you got the content in string format now you can also validate the data
}

Update Question: How to Mock MapToJson Class

this is an update to my previous question. I have a Utility class which I already manage to cover with my unit test except when the condition returns false.
Here is my class:
#Component
public class Utils {
#Autowired
private ObjectMapper mapper = new ObjectMapper();
#Autowired
private LoggingService loggingService;
public <E> String mapToJsonString(E object) {
try {
if (object == null) {
throw new IOException(ErrorMessage.ERROR_PROCESSING_JSON_NULL);
}else {
return mapper.enable(SerializationFeature.INDENT_OUTPUT).writeValueAsString(object); //NullPointer Here
}
} catch (IOException e) {
loggingService.logError(this.getClass().getName(), "1", ErrorMessage.ERROR_MAPPING_TO_JSONSTRING, e);
return "";
}
}
}
and here is my unit test
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = ATMMonitoringApplication.class, initializers = ConfigFileApplicationContextInitializer.class)
public class ObjectToJsonStringTest {
#SpyBean
private ATM atm;
#Autowired
private Utils utils;
#MockBean
private ObjectMapper mapper;
#MockBean
private LoggingService loggingService;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
myModelClass = new MyModelclass();
myModelClass.setStatus("U");
myModelClass.setTermCode("001");
myModelClass.setLocation("BGC");
}
#Test
public void testObjectToJson() throws JsonProcessingException {
String output = utils.mapToJsonStringmyModelClass
assertNotNull(output);
}
#Test
public void testObjectToJsonNull() throws JsonProcessingException {
String output = utils.mapToJsonString(null);
assertNull(output);
}
#Test
public void testJsonParsingException() {
myModelClass = new MyModelclass();
myModelClass = null;
String output = utils.mapToJsonString(myModelClass);
Mockito.when(loggingService.logError(this.getClass().getName(), "1", ErrorMessage.ERROR_MAPPING_TO_JSONSTRING, new Exception()))
.thenReturn("");
assertThat(output).isEmpty();
}
}
Stack trace says that i have a null pointer on this line of code:
return mapper.enable(SerializationFeature.INDENT_OUTPUT).writeValueAsString(object);
Please help me on this. Thanks
Solved it. I just change this
#Mock
private ObjectMapper mapper;
From #MockBean and it covered the whole class.

Issue with Spring boot Controller with Mockito test case

I am completely new to Mockito and I have to write a test case for my REST Controller, but I am not sure where should I start. Any help would be really appreciated.I've updated my controller based on given suggestion.
Here's my controller:
#RestController
#RequestMapping("/api")
public class TestController {
#Autowired
TestService _testService;
#RequestMapping(value = "/getsearchDetailCourse", method = RequestMethod.GET)
public List<TestDto> getsearchDetailCourse(#RequestParam("courseName") String courseName,
#RequestParam("courseId") Long courseId) throws Exception {
return (List<TestDto>) _testService.searchDetailCourse(courseName, courseId);
}
}
My TestDto:
public class TestDto {
private String numberOfCourse;
private Long courseId;
public TestDto(){}
public TestDto(String numberOfCourse,Long courseId ){
super();
this.numberOfCourse = numberOfCourse;
this.courseId = courseId;
}
public String getNumberOfCourse() {
return numberOfCourse;
}
public void setNumberOfCourse(String numberOfCourse) {
this.numberOfCourse = numberOfCourse;
}
public Long getCourseId() {
return courseId;
}
public void setCourseId(Long courseId) {
this.courseId = courseId;
}
}
Here's my test:
#RunWith(SpringRunner.class)
#WebMvcTest(value = TestController.class, secure = false)
public class TestMethod {
#Autowired
private MockMvc mockMvc;
#MockBean
private TestService testService;
TestDto testDto = new testDto("Test",2744L);
#Test
public void retrieveDetailsForCourse() throws Exception {
Mockito.when(
testService.searchDetailCourse(Mockito.anyString(),
,Mockito.anyLong())).thenReturn(testDto);
RequestBuilder requestBuilder = MockMvcRequestBuilders.get(
"/api/getsearchDetailCourse").accept(
MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
System.out.println(result.getResponse());
String expected = "[{\"numberOfCourse\":\"Testing1\",\"courseId\":2744},{\"numberOfCourse\":\"Testing2\",\"courseId\":2744}]";
JSONAssert.assertEquals(expected, result.getResponse()
.getContentAsString(), false);
}
}
I want to test the controller, please help me correct the test case above.

Resources