JUnit 和 Mockito 的分支覆盖
Branch coverage with JUnit and Mockito
我正在使用 JUnit
API 编写测试用例作为方法。我已经介绍了所有情况,但让我感到困难的是 if
块。当我将鼠标悬停在这条线上时,Cobertura
表示每个条件为 50% 50%,但我不确定如何涵盖这一点。
正在测试的方法:
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
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);
}
让我感到困惑的是我正在模拟的参数 date
,它决定了 end
和 start
变量的值。
if( date.getTimeInMillis() >= start.getTimeInMillis() && date.getTimeInMillis() <= end.getTimeInMillis() ) {}
是我要覆盖的行。
谢谢
首先,您从未告诉您的模拟日历对象在调用 getTimeInMillis()
时要做什么。您需要为每个日历条目添加以下内容:
// Assume `long desiredlong` defined;
Mockito.when(calendar.getTimeInMillis()).thenReturn(desiredlong);
您需要对 date.getTimeInMillis() 在所需范围内的一组日历对象和 date.getTimeInMillis() 在所需范围外的另一组日历对象执行此操作。
最终,涵盖该测试真实面的案例将采用以下形式:
@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));
}
其次,您实际上从未写过任何测试错误的东西 return。为了覆盖另一面,复制上面的内容,但将你的 calendartarget.getTimeInMillis()
设置为 return 像 1000L
这样荒谬的东西,并改变你的断言以反映错误。
您可能还希望将测试用例分成多个方法,这些方法的名称反映了每个单独的测试方法检查的内容,例如 validDatesInRange()
、validDatesNotInRange()
、startDateIsNull()
、endDateIsNull()
、contextIsNull()
。通过这样做,您的测试变得更小并且更容易理解和调试,您的测试运行产生更清晰和更多信息的测试报告,并且一个测试中的失败不会掩盖其他测试中的失败。
我正在使用 JUnit
API 编写测试用例作为方法。我已经介绍了所有情况,但让我感到困难的是 if
块。当我将鼠标悬停在这条线上时,Cobertura
表示每个条件为 50% 50%,但我不确定如何涵盖这一点。
正在测试的方法:
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
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);
}
让我感到困惑的是我正在模拟的参数 date
,它决定了 end
和 start
变量的值。
if( date.getTimeInMillis() >= start.getTimeInMillis() && date.getTimeInMillis() <= end.getTimeInMillis() ) {}
是我要覆盖的行。
谢谢
首先,您从未告诉您的模拟日历对象在调用 getTimeInMillis()
时要做什么。您需要为每个日历条目添加以下内容:
// Assume `long desiredlong` defined;
Mockito.when(calendar.getTimeInMillis()).thenReturn(desiredlong);
您需要对 date.getTimeInMillis() 在所需范围内的一组日历对象和 date.getTimeInMillis() 在所需范围外的另一组日历对象执行此操作。
最终,涵盖该测试真实面的案例将采用以下形式:
@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));
}
其次,您实际上从未写过任何测试错误的东西 return。为了覆盖另一面,复制上面的内容,但将你的 calendartarget.getTimeInMillis()
设置为 return 像 1000L
这样荒谬的东西,并改变你的断言以反映错误。
您可能还希望将测试用例分成多个方法,这些方法的名称反映了每个单独的测试方法检查的内容,例如 validDatesInRange()
、validDatesNotInRange()
、startDateIsNull()
、endDateIsNull()
、contextIsNull()
。通过这样做,您的测试变得更小并且更容易理解和调试,您的测试运行产生更清晰和更多信息的测试报告,并且一个测试中的失败不会掩盖其他测试中的失败。