问题
I am writing a test case using JUnit
API for a method. I've covered all the scenarios but the one that is giving me a hard time is in the if
block. When I hover over this line the Cobertura
states 50% 50% for each condition but I am not exactly sure how to get this covered.
Method under test:
protected boolean isDateWithinTimelineRange( Calendar date, ServiceContext ctx ) {
Calendar end = (Calendar)ctx.getParameter( ServiceConstants.TIMELINE_END );
Calendar start = (Calendar)ctx.getParameter( ServiceConstants.TIMELINE_BEGIN );
if( end != null && start != null ) {
if( date.getTimeInMillis() >= start.getTimeInMillis() && date.getTimeInMillis() <= end.getTimeInMillis() ) {
return true;
} else {
return false;
}
}
return true;
}
JUnit test case:
@Test
public void testIsDateWithinTimelineRange() throws Exception {
ServiceContext context = Mockito.mock(ServiceContext.class);
Calendar calender = Mockito.mock(Calendar.class);
Mockito.when(context.getParameter(Mockito.anyString())).thenReturn(calender);
TestBaseTimelineProvider provider = new TestBaseTimelineProvider();
boolean answer = provider.isDateWithinTimelineRange(calender, context);
assertNotNull(answer);
assertTrue(provider.isDateWithinTimelineRange(calender, context));
// Testing for NULL condition
context = Mockito.mock(ServiceContext.class);
calender = Mockito.mock(Calendar.class);
Mockito.when(context.getParameter(Mockito.anyString())).thenReturn(null);
provider = new TestBaseTimelineProvider();
answer = provider.isDateWithinTimelineRange(calender, context);
assertNotNull(answer);
assertTrue(provider.isDateWithinTimelineRange(calender, context));
// Start date set to null
context = Mockito.mock(ServiceContext.class);
calender = Mockito.mock(Calendar.class);
ServiceConstants constants = new ServiceConstants();
Mockito.when(context.getParameter(ServiceConstants.TIMELINE_END)).thenReturn(calender);
provider = new TestBaseTimelineProvider();
answer = provider.isDateWithinTimelineRange(calender, context);
assertNotNull(constants);
// End date set to null
context = Mockito.mock(ServiceContext.class);
calender = Mockito.mock(Calendar.class);
constants = new ServiceConstants();
Mockito.when(context.getParameter(ServiceConstants.TIMELINE_BEGIN)).thenReturn(calender);
provider = new TestBaseTimelineProvider();
answer = provider.isDateWithinTimelineRange(calender, context);
assertNotNull(constants);
}
What confuses me is the parameter date
that I am mocking and which determines the values for the end
and start
variables.
if( date.getTimeInMillis() >= start.getTimeInMillis() && date.getTimeInMillis() <= end.getTimeInMillis() ) {}
is the line that I want to cover.
Thanks
回答1:
Firstly, you never told your mocked calendar objects what to do when getTimeInMillis()
is called. You need to add the following for each calendar entry:
// Assume `long desiredlong` defined;
Mockito.when(calendar.getTimeInMillis()).thenReturn(desiredlong);
You will need to do this for a set of calendar objects where the date.getTimeInMillis() is in the desired range, and another set where date.getTimeInMillis() is outside the desired range.
Ultimately, a case that covers the true side of that test would take the form:
@Test
public void validDatesInRange() {
ServiceContext context = Mockito.mock(ServiceContext.class);
Calendar calenderstart = Mockito.mock(Calendar.class);
Mockito.when(calendarstart.getTimeInMillis()).thenReturn(1L);
Calendar calendertarget = Mockito.mock(Calendar.class);
Mockito.when(calendartarget.getTimeInMillis()).thenReturn(2L);
Calendar calenderend = Mockito.mock(Calendar.class);
Mockito.when(calendarend.getTimeInMillis()).thenReturn(3L);
Mockito.when(context.getParameter(ServiceConstants.TIMELINE_END)).thenReturn(calenderend);
Mockito.when(context.getParameter(ServiceConstants.TIMELINE_BEGIN)).thenReturn(calenderstart);
TestBaseTimelineProvider provider = new TestBaseTimelineProvider();
boolean answer = provider.isDateWithinTimelineRange(calendertarget, context);
assertNotNull(answer);
assertTrue(provider.isDateWithinTimelineRange(calendartarget, context));
}
Secondly, you never actually wrote anything that tests for a false return. To cover the other side, copy the above but set your calendartarget.getTimeInMillis()
to return something ridiculous like 1000L
and change your assertions to reflect false.
You may also wish to break your test cases into multiple methods whose names reflect what each individual test method checks for, like validDatesInRange()
, validDatesNotInRange()
, startDateIsNull()
, endDateIsNull()
, contextIsNull()
. By doing so, your tests become smaller and easier to understand and debug, your test runs produce cleaner and far more informative test reports, and a failure in one test will not mask failures in others.
来源:https://stackoverflow.com/questions/37417797/branch-coverage-with-junit-and-mockito