可选类型的单元测试用例
Unit testcase for Optional type
这是我原来的方法:
public Unit getUnitSymbolForCRSCode(Integer crsCode) {
String crsUnitName = getCrsByCode(crsCode).getUnitName();
List<Unit> unitList = getUnits();
Optional<Unit> unit = unitList.stream().filter(u->u.getUnitOfMeasureName().equalsIgnoreCase(crsUnitName)).findFirst();
if(!unit.isPresent()){
throw new DataNotFoundException(String.format("Failed to retrieve unit details for %s.",crsUnitName));
}
return unit.get();
}
像下面这样写测试用例的时候,有一个分支没有覆盖。我无法抛出 DataNotFoundException。
@Test
public void testGetUnitSymbolForCRSCodeThrowingDataNotFoundException() {
Unit unitObj = new Unit();
Mockito.when(geoCalService.search(Mockito.any(SearchFilter.class)))
.thenReturn(TestDataFactory.getSearchResultResponseForCRS());
Mockito.when(uomService.getUnits()).thenReturn(Arrays.asList(unitObj));
thrown.expect(DataNotFoundException.class);
shellGeodeticService.getUnitSymbolForCRSCode(50015);
}
我收到类似
的错误
java.lang.AssertionError: Expected test to throw an instance of com.shell.geodetic.exception.DataNotFoundException.
虽然 UnitObj 是空的,但它没有抛出 DataNotFoundException。请协助。
public static List<Unit> getUnitList() {
List<Unit> unitList= new ArrayList<Unit>();
unitList.add(new Unit("dega","Degree"));
unitList.add(new Unit("ft[US]","US Survey foot"));
unitList.add(new Unit("m","Meter"));
unitList.add(new Unit("ft[Se]","Sear's Foot"));
unitList.add(new Unit("ft[GC]","Gold Coast Foot"));
unitList.add(new Unit("ft","International Foot"));
unitList.add(new Unit("link[Cla]","Clarke's Link"));
unitList.add(new Unit("gon","Grad"));
return unitList;
}
public CRS getCrsByCode(Integer code) {
SearchResultResponse response = searchCode(String.valueOf(code), 180224);
List<DisplayItem> crsDisplayItems = response.getDisplayItems();
if (crsDisplayItems.isEmpty()) {
throw new DataNotFoundException("CRS not found with code " + code + ": " + response.getSearchMessage());
}
return Util.convertToCrsVoList(crsDisplayItems).get(0);
}
我相信,最简单的是 unitList
,例如在 filter
操作之后,流将为空,即其单位的 none 应该具有相同的度量名字.
在这种情况下,findFirst
将 return Optional.empty()
如文档中所述。
最简单的做法是:
Mockito.when(uomService.getUnits()).thenReturn(Collections.emptyList()))
你让我们陷入了越来越多最终提供一些数据的方法的困境。
下面是您通常如何编写此类内容。
class MyService {
CrsService crsService;
UnitService unitService;
public Unit getUnitSymbolForCRSCode(Integer crsCode) {
String crsUnitName = crsService.getCrsByCode(crsCode).getUnitName();
return unitService.getUnits().stream()
.filter(u->u.getUnitOfMeasureName().equalsIgnoreCase(crsUnitName))
.findFirst()
.orElseThrow(() ->
new DataNotFoundException(String.format(
"Failed to retrieve unit details for %s.",crsUnitName));
}
这就是您测试它的方式 (JUnit 5):
@ExtendWith(MockitoExtension.class)
class MyServiceTest {
@Mock crsService;
@Mock unitService;
@InjectMocks MyService;
@Test
void testNoDataException() {
CRS crs = mock(CRS.class);
when(crsService.getCrsByCode(any())).thenReturn(crs);
when(unitService.getUnits()).thenReturn(Collections.emptyList());
assertThrows(DataNotFoundException.class,
() -> sut.getUnitSymbolForCRSCode(123));
}
}
为了完整起见,这将是您稍后发布的 CrsService
和 UnitService
:
class FixedUnitService implements UnitService {
public List<Unit> getUnits() {
List<Unit> unitList= new ArrayList<Unit>();
unitList.add(new Unit("dega","Degree"));
unitList.add(new Unit("ft[US]","US Survey foot"));
unitList.add(new Unit("m","Meter"));
unitList.add(new Unit("ft[Se]","Sear's Foot"));
unitList.add(new Unit("ft[GC]","Gold Coast Foot"));
unitList.add(new Unit("ft","International Foot"));
unitList.add(new Unit("link[Cla]","Clarke's Link"));
unitList.add(new Unit("gon","Grad"));
return unitList;
}
}
class LookupCrsService implements CrsService {
public Crs getCrsByCode(int id) {
SearchResultResponse response = searchCode(String.valueOf(code), 180224);
List<DisplayItem> crsDisplayItems = response.getDisplayItems();
if (crsDisplayItems.isEmpty()) {
throw new DataNotFoundException("CRS not found with code " + code + ": " + response.getSearchMessage());
}
return Util.convertToCrsVoList(crsDisplayItems).get(0);
}
}
您可以完全单独测试这些 类。
这是我原来的方法:
public Unit getUnitSymbolForCRSCode(Integer crsCode) {
String crsUnitName = getCrsByCode(crsCode).getUnitName();
List<Unit> unitList = getUnits();
Optional<Unit> unit = unitList.stream().filter(u->u.getUnitOfMeasureName().equalsIgnoreCase(crsUnitName)).findFirst();
if(!unit.isPresent()){
throw new DataNotFoundException(String.format("Failed to retrieve unit details for %s.",crsUnitName));
}
return unit.get();
}
像下面这样写测试用例的时候,有一个分支没有覆盖。我无法抛出 DataNotFoundException。
@Test
public void testGetUnitSymbolForCRSCodeThrowingDataNotFoundException() {
Unit unitObj = new Unit();
Mockito.when(geoCalService.search(Mockito.any(SearchFilter.class)))
.thenReturn(TestDataFactory.getSearchResultResponseForCRS());
Mockito.when(uomService.getUnits()).thenReturn(Arrays.asList(unitObj));
thrown.expect(DataNotFoundException.class);
shellGeodeticService.getUnitSymbolForCRSCode(50015);
}
我收到类似
的错误java.lang.AssertionError: Expected test to throw an instance of com.shell.geodetic.exception.DataNotFoundException.
虽然 UnitObj 是空的,但它没有抛出 DataNotFoundException。请协助。
public static List<Unit> getUnitList() {
List<Unit> unitList= new ArrayList<Unit>();
unitList.add(new Unit("dega","Degree"));
unitList.add(new Unit("ft[US]","US Survey foot"));
unitList.add(new Unit("m","Meter"));
unitList.add(new Unit("ft[Se]","Sear's Foot"));
unitList.add(new Unit("ft[GC]","Gold Coast Foot"));
unitList.add(new Unit("ft","International Foot"));
unitList.add(new Unit("link[Cla]","Clarke's Link"));
unitList.add(new Unit("gon","Grad"));
return unitList;
}
public CRS getCrsByCode(Integer code) {
SearchResultResponse response = searchCode(String.valueOf(code), 180224);
List<DisplayItem> crsDisplayItems = response.getDisplayItems();
if (crsDisplayItems.isEmpty()) {
throw new DataNotFoundException("CRS not found with code " + code + ": " + response.getSearchMessage());
}
return Util.convertToCrsVoList(crsDisplayItems).get(0);
}
我相信,最简单的是 unitList
,例如在 filter
操作之后,流将为空,即其单位的 none 应该具有相同的度量名字.
在这种情况下,findFirst
将 return Optional.empty()
如文档中所述。
最简单的做法是:
Mockito.when(uomService.getUnits()).thenReturn(Collections.emptyList()))
你让我们陷入了越来越多最终提供一些数据的方法的困境。
下面是您通常如何编写此类内容。
class MyService {
CrsService crsService;
UnitService unitService;
public Unit getUnitSymbolForCRSCode(Integer crsCode) {
String crsUnitName = crsService.getCrsByCode(crsCode).getUnitName();
return unitService.getUnits().stream()
.filter(u->u.getUnitOfMeasureName().equalsIgnoreCase(crsUnitName))
.findFirst()
.orElseThrow(() ->
new DataNotFoundException(String.format(
"Failed to retrieve unit details for %s.",crsUnitName));
}
这就是您测试它的方式 (JUnit 5):
@ExtendWith(MockitoExtension.class)
class MyServiceTest {
@Mock crsService;
@Mock unitService;
@InjectMocks MyService;
@Test
void testNoDataException() {
CRS crs = mock(CRS.class);
when(crsService.getCrsByCode(any())).thenReturn(crs);
when(unitService.getUnits()).thenReturn(Collections.emptyList());
assertThrows(DataNotFoundException.class,
() -> sut.getUnitSymbolForCRSCode(123));
}
}
为了完整起见,这将是您稍后发布的 CrsService
和 UnitService
:
class FixedUnitService implements UnitService {
public List<Unit> getUnits() {
List<Unit> unitList= new ArrayList<Unit>();
unitList.add(new Unit("dega","Degree"));
unitList.add(new Unit("ft[US]","US Survey foot"));
unitList.add(new Unit("m","Meter"));
unitList.add(new Unit("ft[Se]","Sear's Foot"));
unitList.add(new Unit("ft[GC]","Gold Coast Foot"));
unitList.add(new Unit("ft","International Foot"));
unitList.add(new Unit("link[Cla]","Clarke's Link"));
unitList.add(new Unit("gon","Grad"));
return unitList;
}
}
class LookupCrsService implements CrsService {
public Crs getCrsByCode(int id) {
SearchResultResponse response = searchCode(String.valueOf(code), 180224);
List<DisplayItem> crsDisplayItems = response.getDisplayItems();
if (crsDisplayItems.isEmpty()) {
throw new DataNotFoundException("CRS not found with code " + code + ": " + response.getSearchMessage());
}
return Util.convertToCrsVoList(crsDisplayItems).get(0);
}
}
您可以完全单独测试这些 类。