I am getting null pointer exception at if condition in the below method.Here is my method and junit test class i am working.
METHOD
#Override
public Event getDisplayEventDetails(String ceccid,
String ceocid) {
Event evnt = null;
if(!(validate.isStringBlank(ceccid)))
{
if(!(validate.isStringBlank(ceocid)))
{
String dispEventUri = eventServicesUrl;
eventSrvcLogger.debug("dispEventUri..."+dispEventUri);
try {
ResponseEntity<Event> responseEntity = restTemplate.getForEntity(dispEventUri , Event.class);
evnt=responseEntity.getBody();
if(responseEntity.getStatusCode().toString().equals("200")){
if(evnt.getValue().length > 0){
for(int i=0;i<evnt.getValue().length;i++){
DisplayValue val = new DisplayValue();
val = evnt.getValue()[i];
eventSrvcLogger.debug(val.toString());
}
} else{
evnt.setStatusCode(responseEntity.getStatusCode().toString());
evnt.setStatus(Boolean.FALSE);
evnt.setMessage("Exception occured in handling the request BAD REQUEST");
}
}
} catch (RestClientException e) {
eventSrvcLogger.error("DisplayEventServiceImpl displayEventDetail() RestClientException",
e);
}
}
}
return evnt;
}
Junit class
#Test
public void testGetDisplayEventDetails() throws Exception{
//test setup with mocking, expectations, data population
String eventServicesUrl = "http://restUrl";
Event evnt = newEvent();
ResponseEntity<Event> responseEntity = new ResponseEntity<Event>(evnt, HttpStatus.OK);
DisplayValue[] dv = new DisplayValue[1];
DisplayValue dvalue = new DisplayValue();
dvalue.setFirst_name("Ron");
dv[0] =dvalue;
evnt.setValue(dv);
new NonStrictExpectations() {
{
restTemplate.getForEntity(anyString,evnt.class );returns(responseEntity);
}
};
EventService evntSrvcImpl = new EventServiceImpl();
ReflectionTestUtils.setField(evntSrvcImpl,"eventServicesUrl", eventServicesUrl);
ReflectionTestUtils.setField(evntSrvcImpl,"restTemplate", restTemplate);
}
//execute your test case
Event evnt1 = evntSrvcImpl.getDisplayEventDetails("ceccid", "ceocid");
//perform verifications and assertions
assertNotNull(evnt);
assertEquals(evnt.getValue()[0].getName(), evnt1.getValue()[0].getName());
}
On debugging its throwing null pointer exception
at this line of code
if(responseEntity.getStatusCode().toString().equals("200"))
How to set that value in the junit test class ?
I got it by adding below lines to junit test class:
HttpStatus statusCode= HttpStatus.OK;,
responseEntity.getStatusCode(); returns(statusCode);
Related
I have this complicated method. I want to mock just the result. All what is inside should basically be ignored. I am using Mockito .
class JiraManager
{
public static List<Issue> searchMitarbeiterIssue(String mitarbeiterName) throws JqlParseException, SearchException {
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();
JqlQueryParser jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class);
SearchService searchService = ComponentAccessor.getComponent(SearchService.class);
String jqlSearchString = "project = BLUB AND issuetype = BLOB AND text ~ \"" + myName+ "\""+" AND status = aktive";
final Query query = jqlQueryParser.parseQuery(jqlSearchString);
List<Issue> issues = null;
Query queryToExecute = JqlQueryBuilder.newBuilder(query).buildQuery();
// get results for the jql query
SearchResults searchResult = searchService.search(user, queryToExecute, PagerFilter.getUnlimitedFilter());
try {
Method newGetMethod = null;
try {
newGetMethod = SearchResults.class.getMethod("getIssues");
} catch (NoSuchMethodException e) {
try {
LOGGER.warn("SearchResults.getIssues does not exist - trying to use getResults!");
newGetMethod = SearchResults.class.getMethod("getResults");
} catch (NoSuchMethodError e2) {
LOGGER.error("SearchResults.getResults does not exist!");
}
}
if (newGetMethod != null) {
issues = (List<Issue>) newGetMethod.invoke(searchResult);
} else {
LOGGER.error("ERROR NO METHOD TO GET ISSUES !");
throw new RuntimeException("ICT: SearchResults Service from JIRA NOT AVAILABLE (getIssue / getResults)");
}
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
LOGGER.error("Jql Helper can not get search result (ICT)", e);
} catch (Exception e) {
LOGGER.error("Jql Helper can not get search result - other exception (ICT)", e);
}
return issues;
}
}
I do not want Mockito to run all the Code inside the method. It should just return the List . That's all . So I tried this:
try (MockedStatic<JiraManager> utilities = Mockito.mockStatic(JiraManager.class)) {
utilities.when(() -> JiraManager.searchMitarbeiterIssue(any()))
.thenReturn(Collections.singletonList(mitarbeiterIssueResult));
assertTrue(JiraManager.searchMitarbeiterIssue("").size() == 1);
}
But it is not working. It always returns null. Why ?? Is the code inside the method executed ? What is Mockito exactly doing ?
Below works for me.
Create MockedStatic class field
private MockedStatic<MyUtilClassWithStaticMethods> myUtil;
Initialise MockedStatic before each test case
#BeforeEach
void initialiseWorker() {
myUtil = mockStatic(MyUtilClassWithStaticMethods.class);
}
Close MockedStatic after each test case
#AfterEach
public void close() {
myUtil.close();
}
Mock static method behaviour in test case
#Test
void test() {
when(MyUtilClassWithStaticMethods.staticMethod(any())).thenReturn(null);
}
You can return list instead of null here.
How can I test for 'bad input' using JUnit? I am trying to instantiate a Flight object by passing the first parameter of it a value that cannot be parsed to type LocalTime. When I do so, the "fail" in the JUnit testConstructor method gives an error. How should I handle this Exception so it can pass the JUnit test without error? Thank you
protected Flight(String scheduledTime, String eventType, String identifier) {
try {
this.scheduledTime = LocalTime.parse(scheduledTime);
this.eventType = EventType.valueOf(eventType);
this.identifier = identifier;
this.actualTime = null;
this.runwayUsed = null;
}
catch(Exception e) {
System.out.println(e + " Flight constructor");
}
} //end of constructor
Below in the try/catch block is the JUnit code that is giving the error.
#Test
public void testConstructor() {
Flight f1 = new Flight("00:00", "ARRIVAL", "A001");
Flight f2 = new Flight("00:00", "DEPARTURE", "D001");
assertEquals(LocalTime.parse("00:00"), f1.getScheduledTime());
assertEquals(EventType.ARRIVAL, f1.getEvent());
assertEquals("A001", f1.getIdent());
assertEquals(null, f1.getActualTime());
assertEquals(null, f1.getRunwayUsed());
assertEquals(LocalTime.parse("00:00"), f2.getScheduledTime());
assertEquals(EventType.DEPARTURE, f2.getEvent());
assertEquals("D001", f2.getIdent());
assertEquals(null, f2.getActualTime());
assertEquals(null, f2.getRunwayUsed());
//invalid entry for scheduledTime
try {
Flight f3 = new Flight("00:0j", "ARRIVAL", "A001");
fail("Expected exception");
} //end of try
catch(Exception e) {
System.out.println(e);
} //end of catch
}
First, as pointed out by #binoternary your constructor doesn't throw exception outside of itself it just logs it instead.
Second, to make your test pass only if specific exception is thrown then you need to add this annotation to the test method:
#Test(expected = DateTimeParseException.class) // or any other exception class expected to be thrown
public void testException() {
Flight f3 = new Flight("00:0j", "ARRIVAL", "A001");
}
Don't catch Exception in the constructor.
protected Flight(final String scheduledTime,
final String eventType,
final String identifier) {
this.scheduledTime = LocalTime.parse(scheduledTime);
this.eventType = EventType.valueOf(eventType);
this.identifier = identifier;
this.actualTime = null;
this.runwayUsed = null;
}
A better design might be to change the constructor to this:
protected Flight(final LocalTime scheduledTime,
final EventType eventType,
final String identifier) {
...
}
Also, I'd suggest your single test be broken up into three separate, well-named, tests.
Good luck.
You have some options.
The first one is to catch the exception in the constructor method. In this scenario, you should adapt your test method.
So, the constructor would be something like:
protected Flight(String scheduledTime, String eventType, String identifier) {
this.identifier = identifier;
this.actualTime = null;
this.runwayUsed = null;
try {
this.scheduledTime = LocalTime.parse(scheduledTime);
} catch(Exception e) {
System.out.println(e + " Flight constructor - scheduledTime problem");
}
try {
this.eventType = EventType.valueOf(eventType);
} catch(Exception e) {
System.out.println(e + " Flight constructor - eventType problem");
}
}
Consequently, your test should be:
#Test
public void testConstructor() {
Flight f = new Flight("00:0j", "ARRIVAL", "A001");
assertNull(f.scheduledTime);
assertEquals("A001", f.identifier);
// other asserts
}
The second option is to throw the exception if something goes wrong in the constructor. In this case, the constructor would be like:
protected Flight(String scheduledTime, String eventType, String identifier) {
this.identifier = identifier;
this.actualTime = null;
this.runwayUsed = null;
this.scheduledTime = LocalTime.parse(scheduledTime);
this.eventType = EventType.valueOf(eventType);
}
And your test could be like:
#Test
public void testConstructor() {
try {
new Flight("00:0j", "ARRIVAL", "A001");
fail("Expected exception");
} catch(Exception e) {
assertNotNull(e);
}
}
or
#Test(expected = Exception.class) // You can also specialize this exception to DateTimeParseException or any other
public void testConstructor() {
new Flight("00:0j", "ARRIVAL", "A001");
}
As you see, you have several options.
What you are doing is correct, but maybe it would be clearer if you were using Junit 4 you can specify the exception that you expect in the #Test annotation, see here for details.
If the test fails it's because your Flight constructor is not throwing any exception.
This question already has answers here:
Mocking Files in Java - Mock Contents - Mockito
(3 answers)
Closed 6 years ago.
I have the following code:
public class FolderServiceImpl implements FolderService {
private static final Logger L = LoggerFactory.getLogger(FolderServiceImpl.class);
public int getStatus(String folderPath) {
int status = 0;
File folderStatusFile = new File(folderPath, ".folderstatus");
if (folderStatusFile.exists()) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(folderStatusFile));
String line = br.readLine();
status = Integer.parseInt(line);
} catch (Exception e) {
L.error("can't read file " + folderStatusFile.getAbsolutePath(), e);
status = 4;
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
L.warn("could not close reader ", e);
}
}
}
} else {
status = 3;
}
return status;
}
}
I want to test this method without creating actual files for every case. I should be using Java 1.7, JUnit 4, Mockito and/or PowerMockito.
Any ideas on how to do that?
I am talking about mocking either the data source or simply changeing the input for the method.
My test looks something like this:
`#Rule
public TemporaryFolder folder = new TemporaryFolder();
private FolderServiceImpl serviceToTest = new FolderServiceImpl();
private String folderPath;
#Before
public void setUp() {
folderPath = folder.getRoot().getAbsolutePath();
try {
folder.newFile(".folderstatus");
} catch (IOException e) {
e.printStackTrace();
}
}
#Test
public void shouldReturnFolderStatus3WhenFolderStatusIsNotFound() {
// given
deleteFolderStatusFile();
// actual
int status = serviceToTest.getFolderStatus(folderPath);
// expected
assertEquals(3, status);
}
#Test
public void shouldReturnFolderStatus4WhenTheStatusIsUnreadable() {
// given
writeStatusToTestFile("Test");
// actual
int status = serviceToTest.getFolderStatus(folderPath);
// expected
assertEquals(4, status);
}
#Test
public void shouldReturnFolderStatusInTheFile() {
// given
writeStatusToTestFile("1");
// actual
int status = serviceToTest.getFolderStatus(folderPath);
// expected
assertEquals(1, status);
}
private void writeStatusToTestFile(String status) {
Path file = Paths.get(folder.getRoot().getAbsolutePath(), ".folderstatus");
try {
Files.write(file, status.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
private void deleteFolderStatusFile() {
Path file = Paths.get(folder.getRoot().getAbsolutePath(), ".folderstatus");
try {
Files.delete(file);
} catch (IOException e) {
e.printStackTrace();
}
}`
Although the answer of #BenHeid may work I'd suggest to change to different approach.
IMHO when ever I use PowerMock(-ito) it is a surrender to bad design.
Also the PowerMock solution will confuse test coverage tools since it changes the Applications byte code after it has been instrumented for coverage measurement.
So the approach I'd prefer is to stick to Clean Code and OOP rules.
One of them is separation of concerns.
In your case the method creates some infrastructure classes (dependencies) to work with, namely FileReader and BufferedReader.
But the instantiation of (direct) dependencies is not a responsibility of a class containing business logic.
Therefore I'd suggest to refactor that code out into a separate class:
class ReaderFactory {
public BufferedReader createFor(File file) throws FileNotFoundException {
return new BufferedReader(new FileReader(file));
}
}
Your Class would change to this:
class FolderServiceImpl {
private static final Logger L = LoggerFactory.getLogger(FolderServiceImpl.class);
private final ReaderFactory readerFactory;
FolderServiceImpl(ReaderFactory readerFactory) {
this.readerFactory = readerFactory;
}
public int getStatus(String folderPath) {
int status = 0;
File folderStatusFile = new File(folderPath, ".folderstatus");
// try "with resource" takes care of closing the reader
try (BufferedReader br = readerFactory.createFor(folderStatusFile);) {
String line = br.readLine();
status = Integer.parseInt(line);
} catch (IOException e) {
status = 3;
} catch (Exception e) {
L.error("can't read file " + folderStatusFile.getAbsolutePath(), e);
status = 4;
}
return status;
}
}
And your Test would be this:
public class FolderServiceImplTest {
private static final String ANY_FILE_NAME = "";
#Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
#Rule
public ExpectedException thrown = ExpectedException.none();
#Mock
private ReaderFactory readerFactory;
#InjectMocks
FolderServiceImpl sut;
#Test
public void getStatus_FileNotExisting_returnStatus3() throws Exception {
// arrange
Mockito.doThrow(new FileNotFoundException("UnitTest")).when(readerFactory).createFor(Mockito.any(File.class));
// act
int status = sut.getStatus(ANY_FILE_NAME);
// assert
Assert.assertThat("status",status,CoreMatchers.equalTo(3));
}
#Test
public void getStatus_ValidFile_returnFileContentAsInt() throws Exception {
// arrange
BufferedReader bufferedReader = Mockito.mock(BufferedReader.class);
Mockito.doReturn(bufferedReader).when(readerFactory).createFor(Mockito.any(File.class));
Mockito.doReturn("4711").when(bufferedReader).readLine();
// act
int status = sut.getStatus(ANY_FILE_NAME);
// assert
Assert.assertThat("status",status,CoreMatchers.equalTo(4711));
}
}
You have to use something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest(tests.class)
public class test {
#Test
public void test() throws Exception {
File fileMock = Mockito.mock(File.class);
PowerMockito.whenNew(File.class).withArguments(Mockito.anyString(), Mockito.anyString()).thenReturn(fileMock);
FolderServiceImpl sut = new FolderServiceImpl sut ();
Mockito.when(fileMock.exists()).thenReturn(true);
sut.getStatus("");
// Your verifications..
}
}
Powermock will mock the File object which is created in the method getStatus of your class. With Mockito.when you can say what is the return value of folderStatusFile.exists() in your code.
EDIT
I have included the following two jars with maven, but you don't need to use maven: https://mvnrepository.com/artifact/org.powermock/powermock-module-junit4/1.4.6 and https://mvnrepository.com/artifact/org.powermock/powermock-api-mockito/1.4.9 and https://mvnrepository.com/artifact/org.mockito/mockito-all/1.10.19
-> controller.java
public controller() {
public controller(DataInterpreter interpret,ControllerClientUtility util, InterfaceConnection inter) {
interpreter = interpret;
utility = util;
interfaced = inter;
}
}
...
public void closeOne(String vpnSessionId) throws Exception {
try{
if ( interfaced.connect() && (interfaced.CheckIntegrity(SessionId)) ){
interfaced.kill(vpnSessionId);
}else{
closeAll();
}
}catch(Exception e){
if ( e.getMessage().startsWith("INTERFACE_ERR:") ){
closeAll();
}else{
throw new Exception(e);
}
}
}
-> methods in InterfaceConnection.java
public String getReponseFor(String command) throws Exception{
if (send(command)){
return receive();
}
else{
throw new Exception("INTERFACE_ERR: Could not get Response");
}
}
public List<String> getListOfConnections() throws Exception{
String statusResponse = getReponseFor("something");
..(regex searches and then make a list connectionsConnected)
return connectionsConnected;
}
public boolean CheckIntegrity(String SessionId){
try {
List<String> connections = new ArrayList<String>();
connections = getListOfConnections();
if (connections.contains(SessionId)){
return true;
}
return false;
}catch(Exception e){
return false;
}
}
Is there a way to mock the output of getListOfConnections ? I tried doing something like this but did not work
-> controllerTest.java
#Mock private InterfaceConnection interfaced;
#Before
public void beforeTests() throws Exception {
MockitoAnnotations.initMocks(this);
impl = new Controller(interpreter,utility,interfaced);
...
#Test
public void testDisconnectOneSessionWithBadSessionId_sendCommand() throws Exception{
String badSessionId = "123:123";
List<String> mockConnections = new ArrayList<String>();
mockConnections.add("asdasds");
when(interfaced.getListOfConnections()).thenReturn(mockConnections);
impl.closeOne(badSessionId);
Mockito.verify(utility)....
}
I hope I'm clear, thanks in advance.
I am new to JUnit and I have to test a method using JUnit api. One method internall calls another. My test case goes inside the method but while catchign the exception it fails.
Method under test is
public void checkANDCondition( Map<String, Message> messagesMap ) throws EISClientException
{
List<String> codes = getMessageCodes();
if(isAllReturnedMessagesContainCodes(codes, messagesMap))
{
StringBuffer buff = new StringBuffer("All of the specified message codes matched returned errors.");
for(String code: codes )
{
Message message = messagesMap.get(code);
buff.append(message.getMessageCode() + ": " + message.getMessageType() + ": " + message.getMessageText() + " ");
}
throw new EISClientException(buff.toString());
}
}
public boolean isAllReturnedMessagesContainCodes(List<String> codes, Map<String, Message> messagesMap)
{
if(codes!=null)
{
for(String code: codes)
{
if(!messagesMap.containsKey(code))
{
return false;
}
}
}
return true;
}
What I have done so far is
#Test
public void testPostProcess() throws Exception {
clientResponse = mock(ClientResponse.class);
MessageToExceptionPostProcessFilter postProcessFilter = new MessageToExceptionPostProcessFilter();
RetrieveBillingServiceResponse serviceResponse = new RetrieveBillingServiceResponse();caughtException = false;
try {
postProcessFilter.setCondition(ConditionOperator.AND);
List<String> messagesCodes = new ArrayList<String>();
messagesCodes.add("200");
messagesCodes.add("400");
Message message = new Message();
message.setMessageCode("200");
message.setMessageType(MessageTypeEnum.MESSAGE_TYPE_INFO);
message.setMessageText("Service completed successfully");
serviceResponse.setMessages(Arrays.asList(message));
postProcessFilter.setMessageCodes(messagesCodes);
serviceResponse = postProcessFilter.postProcess(serviceResponse, clientResponse);
assertNotNull(serviceResponse.getMessages());
} catch (EISClientException ex) {
caughtException = true;
assertEquals("All of the specified message codes matched returned errors.", ex.getMessage());
}
assertTrue(caughtException);
}
How can I make it pass?
Thanks
#Test(expected = EISCLientException.class)
public void testPostProcess() throws Exception {
...
serviceResponse.getMessages();
fail("Shouldn't reach this point");
}
That way you don't need to catch, with expected if it does not get throw a EISClientException it will fail.
edit: There are two times I can think of where you wouldn't want to use this.
1) You are mocking exceptions that are thrown mock(exception.class);
this i believe then throws some Mockito excpetion and it will not match the expected exception.
2) You are wrapping caught exceptions in your code, and throwing a generic exception. Example of code:
try {
} catch (FileParseException e){
throw new (ProjectFailingException(e, "file is bad");
}
if you have multiple catches and are wrapping them as ProjectFailingExceptions then you may want to catch in the test like this...
#Test ( expected = FileParseException.class)
public void testProcess() {
try {
...
} catch (ProjectFailingException e){
throw e.getCause();
}
Then the proper exception is thrown and you can make sure that process isn't throwing an exception from a a different catch.