mockito junit未涵盖接口中的java方法
我正在使用mockito junit测试我的一段代码。随着工作的进行,我发现我正在测试的主文件中实现了一个接口,当测试运行时,我发现接口方法被称为get的那一行被覆盖了,但真正的方法没有被覆盖
这是主文件的代码:
public class ExtractCurrencyDataTask {
private static final Logger LOGGER = LoggerFactory.getLogger(ExtractCurrencyDataTask.class);
@Autowired
private ExtractCurrencyService extractCurrencyService;
public void writeCurrencyListToFile(List<Currency> currencyList) {
if (currencyList != null && !currencyList.isEmpty()) {
String dir = "A path";
String fileName = "A filename";
String writeToFile = dir + "/" + fileName + ".writing";
String renameFile = dir + "/" + fileName + ".dat";
BufferedWriter writer = null;
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(writeToFile);
writer = new BufferedWriter(fileWriter);
extractCurrencyService.extractCurrencyList(currencyList, writer);
} catch (Exception e) {
throw new RuntimeException("Error writing Currency codes", e);
} finally {
if (writer != null) {
try {
writer.close();
fileWriter.close();
} catch (IOException e) {
LOGGER.info("Exception occured while closing the file writer", e);
}
moveFile(writeToFile, renameFile);
}
}
}
}
private void moveFile(String writeToFile, String renameFile) {
try {
FileUtils.moveFile(FileUtils.getFile(writeToFile), FileUtils.getFile(renameFile));
} catch (IOException e) {
LOGGER.info("Exception occured while moving file from writing to dat", e);
}
}
这里extractCurrencyService
是我提到的接口
界面:
public interface ExtractCurrencyService {
public void extractCurrencyList(List<Currency> currency, Writer writer);
}
此方法定义由实现相同接口文件名的另一个文件完成:ExtractCurrencyServiceImpl。爪哇
public class ExtractCurrencyServiceImpl implements ExtractCurrencyService {
private static final String SEP = "|";
private static final String NEWLINE = "\n";
@Override
public void extractCurrencyList(List<Currency> currencyList, Writer writer) {
if (currencyList != null) {
currencyList.forEach(currency -> {
String code = currency.getCode();
String name = currency.getName() == null ? "" : currency.getName();
Long noOfDecimals = currency.getNumberOfDecimals();
RoundingMethodValue roundingMethod = currency.getRoundingMethod();
boolean isDealCurrency = currency.isDealCurrency();
String description = currency.getDescription() == null ? "" : currency.getDescription();
try {
writer.write(createCurrencyDataLine(code,
name,
noOfDecimals,
roundingMethod,
isDealCurrency,
description));
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
}
private String createCurrencyDataLine(String code,
String name,
Long noOfDecimals,
RoundingMethodValue roundingMethod,
boolean isdealCurrency,
String description) {
return code + SEP + name + SEP + noOfDecimals.toString() + SEP + roundingMethod.toString() + SEP
+ isdealCurrency + SEP + description + NEWLINE;
}
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
这是测试文件:
@RunWith(MockitoJUnitRunner.class)
public class ExtractCurrencyDataTaskTest {
@Mock
private Currency mockCurrency;
@Mock
private ExtractCurrencyService mockExtractCurrencyService;
@Mock
private BufferedWriter mockBufferWriter;
@Mock
private Bean mockBean;
@InjectMocks
private ExtractCurrencyDataTask extractCurrencyDataTask;
@Test
public void writeCurrencyListToFileTest() {
List<Currency> currencyList = new ArrayList();
when(mockCurrency.getCode()).thenReturn("USD");
when(mockCurrency.getNumberOfDecimals()).thenReturn((long) 2);
when(mockCurrency.getRoundingMethod()).thenReturn(enum value);
when(mockCurrency.isDealCurrency()).thenReturn(true);
when(mockCurrency.getName()).thenReturn("US Dollars");
when(mockCurrency.getDescription()).thenReturn("Currency Description");
currencyList.add(mockCurrency);
extractCurrencyDataTask.writeCurrencyListToFile(currencyList);
}
}
这是自动连线bean的配置
@Bean
public ExtractCurrencyService extractCurrencyService() {
return new ExtractCurrencyServiceImpl();
}
正如您所看到的,这个过程的实际输出是,将在一个路径中创建一个文件,其中包含一些数据。在这个测试中,我模拟数据并将其传递给主文件。主文件是在各自路径中创建的文件,但文件中没有数据。 数据写入部分采用接口方式完成。这是我需要帮助的地方
提前谢谢
# 1 楼答案
您正在将模拟的
ExtractCurrencyService
注入到测试的类中。因此,测试是使用这个模拟实例而不是ExtractCurrencyServiceImpl
运行的。当前的行为是ExtractCurrencyDataTask
测试的类正在调用extractCurrencyService#extractCurrencyList
,但是这个extractCurrencyService
是一个模拟的,不是您真正的实现,因此调用已经完成,但它什么也不做如果您想要单元测试
ExtractCurrencyDataTask
,那么这没关系,但是您可能应该断言对extractCurrencyService#extractCurrencyList
的调用是按照您期望的方式完成的如果您想要单元测试
ExtractCurrencyServiceImpl
,那么为这个类创建一个单元测试如果您想测试这两个类之间的交互,那么创建一个集成测试,其中
ExtractCurrencyDataTask
注入了ExtractCurrencyServiceImpl
的真实实例,而不是模拟实例