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.
Related
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'.
I have a class JobDelegate for which i am writing unit tests using mockito. I am unable to mock the HTTPOperations class. I have tried using setter injection from test class as well. But it does not work. Below the latest revision of the code. I tried using Power mock. but none of them was helpful. I am unable to predict which is going wrong.
Unit Test code
#ContextConfiguration(locations= "file:src/main/webapp/WEB-INF/spring-
context.xml")
#RunWith(SpringJUnit4ClassRunner.class)
//#RunWith(PowerMockRunner.class)
/#PowerMockIgnore({ "javax.xml.*", "org.xml.*", "org.w3c.*" })
//#PrepareForTest({ HTTPOperations.class})
public class JobSubmissionDelegateTest{
private static Logger LOGGER = null;
private JobDelegate jobDelegate ;
private JobManager jobImpl;
#InjectMocks
private HTTPOperations operations;
//#Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
#Before
public void setupTests() {
jobDelegate = new JobDelegate();
jobManager = new DBJobManagerImpl();
operations = new HTTPOperations();
jobManager.setHttpOperations(operations);
jobSubmissionDelegate.setJobImpl(jobManager);
//HTTPOperations httpOperationsSpy =spy(HTTPOperations.class);
//doReturn("{\"response\":\"{\\\"run_id\\\":32423423}\\n\"}").when(myClassSpy).method1();
MockitoAnnotations.initMocks(this);
}
#Test
public void testExecuteJob() throws IOException {
// PowerMockito.mockStatic(HTTPOperations.class);
Mockito.when(operations.submitHttpPostRequest(any(), anyString())).thenReturn("{\"response\":\"{\\\"run_id\\\":32423423}\\n\"}");
//System.out.println("==>"+operations.submitHttpPostRequest(null, ""));
...........
int runID = jobDelegate.executeJob(jobDetails);
System.out.println("Run ID here " + runID);
}
}
public class JobDelegate {
// This is an interface.. and the implementation is passed from spring-
context.xml
#Autowired
private JobManager jobImpl;
public int executeJob(JobDTO jobDto) {
............
return jobImpl.runBatchJob(jobDto);
}
}
public class DBJobManagerImpl implements JobManager{
#Autowired
private URIUtils uriUtils;
#Autowired
private HTTPOperations httpOperations;
#Override
public int runBatchJob(JobDTO jobDto) throws Exception {
UriComponentsBuilder uri = uriUtils.createURI(ConfigUtil.getUrI());
String response = httpOperations.submitHttpPostRequest(uri, runSubmitJson);
System.out.println("Response ==> " +response);
.................
}
}
I was able to resolve the issue using PowerMock.
Below the code
#RunWith(PowerMockRunner.class)
#ContextConfiguration(locations= "file:src/main/webapp/WEB-
INF/Enrichment_Context.xml")
#PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
#PowerMockIgnore({ "javax.xml.*", "org.xml.*", "org.w3c.*",
"javax.management.*" })
#PrepareForTest({ HTTPOperations.class})
public class JobDelegateTest {
#Autowired
private JobDelegate jobSubmissionDelegate;
#Test
public void testExecuteJob() throws IOException {
PowerMockito.mockStatic(HTTPOperations.class);
PowerMockito.when(HTTPOperations.submitHttpPostRequest(Mockito.any(),
Mockito.anyString())).thenReturn("{\"response\":\"{\\\"run_id\\\":32423423}\\n\"}");
...................
int runID = jobSubmissionDelegate.executeJobSubmission(jobDetails);
}
}
I've added an AOP (Aspect Oriented Programming) Aspect to my working project. It does work, but it won't be called when trying to Test it's functionality with an Integration Test.
The problem is, that the aspect is not called when the tests runs through. When using it normally it works fine.
I've tried to create a custom context which is supposed to be loaded for the integration tests, as I thought that the Aspect might not be loaded in the default context for these tests.
As this didn't work i also tried to manually proxy the bean of the aspect, but this didn't work neither.
Here's my integration test class:
#ComponentScan(basePackages = { "package.aspects" })
#RunWith(SpringRunner.class)
#SpringBootTest(classes = ZirafyApp.class)
#ContextConfiguration(classes ={ IntegrationTestAOPConfiguration.class })
public class CellResourceIntTest {
private static CellTestHelper helper = new CellTestHelper();
#Autowired
private PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver;
#Autowired
private ExceptionTranslator exceptionTranslator;
#Autowired
private EntityManager em;
#Autowired
private BusinessFacade businessFacade;
#Autowired
private CellRepository cellRepository;
#Autowired
private AspectModule aspectModule;
private MockMvc restCellMockMvc;
private MappingJackson2HttpMessageConverter jacksonMessageConverter = new MappingJackson2HttpMessageConverter();
private Cell cell;
private Cell parentCell;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
final CellResource cellResource = new CellResource(cellRepository, businessFacade);
this.restCellMockMvc = MockMvcBuilders.standaloneSetup(cellResource)
.setCustomArgumentResolvers(pageableHandlerMethodArgumentResolver)
.setControllerAdvice(exceptionTranslator)
.setConversionService(createFormattingConversionService())
.setMessageConverters(jacksonMessageConverter).build();
}
#Test
#Transactional
public void update_cellDtoWithEmptyName_returnsHttpError422AndCellInDbIsNotUpdated() throws Exception {
AspectJProxyFactory factory = new AspectJProxyFactory(cellRepository);
factory.addAspect(aspectModule);
CellRepository cellRepository = factory.getProxy();
CellDto cellDtoToUpdate = new CellDto.Builder().id(2).name(null).x(-10).active(true).parent(1).build();
Cell parentCell = helper.createCell(1L);
Cell cellToUpdate = helper.createCell(2L);
cellRepository.saveAndFlush(parentCell);
cellRepository.saveAndFlush(cellToUpdate);
restCellMockMvc.perform(put("/api/cells/update")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(cellDtoToUpdate)))
.andExpect(status().is(200));
Cell updatedCell = cellRepository.findOne(2L);
assertEquals(cellToUpdate.getX(), updatedCell.getX());
}
Here the configuration file for the integration test:
#Configuration
#EnableJpaRepositories(basePackages = {"package.repository"})
#ComponentScan("ch.post.pf.aspects")
#EnableAspectJAutoProxy(proxyTargetClass = true)
public class IntegrationTestAOPConfiguration {
#Autowired
private ExceptionTranslator exceptionTranslator;
#Autowired
private EntityManager em;
#Autowired
private CellConverter cellConverter;
#Autowired
private CellTreeService cellTreeService;
#Autowired
private CellService cellService;
#Autowired
private CellRepository cellRepository;
#Autowired
private BusinessFacade businessFacade;
#Autowired
private AspectModule aspectModule;
#Bean
public CellConverter returnCellConverter() {
return cellConverter;
}
#Bean
public AspectModule returnAspectModule() {
return null;//Aspects.aspectOf(AspectModule.class);
}
#Bean
public PageableHandlerMethodArgumentResolver returnPageableArgumentResolver() {
return new PageableHandlerMethodArgumentResolver();
}
#Bean
public ExceptionTranslator returnExceptionTranslator() {
return exceptionTranslator;
}
#Bean
#Primary
public EntityManager returnEntityManager() { return em; }
#Bean
public BusinessFacade returnBusinessFacade() {
return businessFacade;
}
#Bean
public CellTreeService returnCellTreeService() {
return cellTreeService;
}
#Bean
public CellService returnCellService() {
return cellService;
}
}
And here my aspect-file:
#Aspect
#Component
public class AspectModule {
private BusinessFacade businessFacade;
#Autowired
AspectModule(BusinessFacade businessFacade){
this.businessFacade = businessFacade;
}
#Pointcut("execution(* ch.post.pf.web.rest.CellResource.update(..))")
private void update() {}
#Around("update() && args(cell)")
public Object checkIsValidCell(ProceedingJoinPoint pjp, CellDto cell) {
System.out.println("Aspect was run");
final String message = canUpdate(cell);
if (message.equals("cell_valid")) {
try {
return pjp.proceed(); // Calls the usual update() function, if the cell is valid
} catch (Throwable e) {
System.out.println("Something went wrong with the aspects");
System.out.println(e.toString());
return null;
}
} else {
deleteIfCellWasEmpty(cell);
return ResponseUtil.unprocessableEntity(message);
}
}
}
The aspect should keep working as it does right now but it should also work in the integration tests, at the moment it isn't called at all inside those.
I am new to Junits and Mockito, I am writing a Unit test class to test my service class CourseService.java which is calling findAll() method of CourseRepository.class which implements CrudRepository<Topics,Long>
Service Class
#Service
public class CourseService {
#Autowired
CourseRepository courseRepository;
public void setCourseRepository(CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
public Boolean getAllTopics() {
ArrayList<Topics> topicList=(ArrayList<Topics>) courseRepository.findAll();
if(topicList.isEmpty())
{
return false;
}
return true;
}
}
Repository class
public interface CourseRepository extends CrudRepository<Topics,Long>{
}
Domain class
#Entity
#Table(name="Book")
public class Topics {
#Id
#Column(name="Topicid")
private long topicId;
#Column(name="Topictitle",nullable=false)
private String topicTitle;
#Column(name="Topicauthor",nullable=false)
private String topicAuthor;
public long getTopicId() {
return topicId;
}
public void setTopicId(long topicId) {
this.topicId = topicId;
}
public String getTopicTitle() {
return topicTitle;
}
public void setTopicTitle(String topicTitle) {
this.topicTitle = topicTitle;
}
public String getTopicAuthor() {
return topicAuthor;
}
public void setTopicAuthor(String topicAuthor) {
this.topicAuthor = topicAuthor;
}
public Topics(long topicId, String topicTitle, String topicAuthor) {
super();
this.topicId = topicId;
this.topicTitle = topicTitle;
this.topicAuthor = topicAuthor;
}
}
Following is the Junit class I have written but courseRepository is getting initialized to NULL and hence I am getting NullPointerException.
public class CourseServiceTest {
#Mock
private CourseRepository courseRepository;
#InjectMocks
private CourseService courseService;
Topics topics;
#Mock
private Iterable<Topics> topicsList;
#Before
public void setUp() {
MockitoAnnotations.initMocks(CourseServiceTest.class);
}
#Test
public void test_Get_Topic_Details() {
List<Topics> topics = new ArrayList<Topics>();
Mockito.when(courseRepository.findAll()).thenReturn(topics);
boolean result=courseService.getAllTopics();
assertTrue(result);
}
}
Change the setUp() method to:
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
Probably you are dealing with some problem on the framework to make the mocked class be injected by the framework.
I recommend to use Constructor Injection, so you don't need to rely on the reflection and #Inject/#Mock annotations to make this work:
#Service
public class CourseService {
private final CourseRepository courseRepository;
// #Autowired annotation is optional when using constructor injection
CourseService (CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
// .... code
}
The test:
#Test
public void test_Get_Topic_Details() {
List<Topics> topics = new ArrayList<Topics>();
Mockito.when(courseRepository.findAll()).thenReturn(topics);
CourseService courseService = new CourseService(courseRepository);
boolean result = courseService.getAllTopics();
assertTrue(result);
}
I have been looking at other answers but none of the seem to work for me, I have a spring boot application where I am using mongo and kafka. In the main class where my run() method is I am able to #Autowired mongoTemplate and it works but then in another class I did the same and I am getting a null pointer exception on the mongoTemplate.
Here are both classes:
Working
#SpringBootApplication
public class ProducerConsumerApplication implements CommandLineRunner {
public static Logger logger = LoggerFactory.getLogger(ProducerConsumerApplication.class);
public static void main(String[] args) {
SpringApplication.run(ProducerConsumerApplication.class, args).close();
}
#Autowired
private Sender sender;
#Autowired
MongoTemplate mongoTemplate;
#Override
public void run(String... strings) throws Exception {
Message msg = new Message();
msg.setCurrentNode("my_node");
msg.setStartTime(System.currentTimeMillis());
String json = "{ \"color\" : \"Orange\", \"type\" : \"BMW\" }";
ObjectMapper objectMapper = new ObjectMapper();
msg.setTest(objectMapper.readValue(json, new TypeReference<Map<String,Object>>(){}));
sender.send(msg);
mongoTemplate.createCollection("test123");
mongoTemplate.dropCollection("test123");
}
Not working
#Component
public class ParentNode extends Node{
#Autowired
public MongoTemplate mongoTemplate;
public void execute(Message message) {
try{
// GET WORKFLOWS COLLECTION
MongoCollection<Document> collection = mongoTemplate.getCollection("workflows");
} catch(Exception e){
e.printStackTrace();
}
}
}
Thank you for the help. It is much appreciated.
can you try to inject dependency with setter or constructor:
Method 1:
#Component
public class ParentNode extends Node{
#Autowired
public ParentNode(MongoTemplate mongoTemplate){
this.mongoTemplate = mongoTemplate;
}
private final MongoTemplate mongoTemplate;
public void execute(Message message) {
try{
// GET WORKFLOWS COLLECTION
MongoCollection<Document> collection = mongoTemplate.getCollection("workflows");
} catch(Exception e){
e.printStackTrace();
}
}
Method 2:
#Component
public class ParentNode extends Node{
#Autowired
public void setMongoTemplate(MongoTemplate mongoTemplate){
ParentNode.mongoTemplate = mongoTemplate;
}
static private MongoTemplate mongoTemplate;
public void execute(Message message) {
try{
// GET WORKFLOWS COLLECTION
MongoCollection<Document> collection = mongoTemplate.getCollection("workflows");
} catch(Exception e){
e.printStackTrace();
}
}