首页 > 解决方案 > 接口中的方法没有被 mockito junit 覆盖

问题描述

我正在使用 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);

}

这是由另一个实现相同接口 Filename:ExtractCurrencyServiceImpl.java 的文件完成的方法定义

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);
}
}

这是 Autowired bean 的配置

@Bean
public ExtractCurrencyService extractCurrencyService() {
    return new ExtractCurrencyServiceImpl();
}

正如你所看到的,这个过程的真正输出是一个文件将在一个包含一些数据的路径中创建。在这个测试中,我正在模拟数据并将其传递给主文件。主文件是在相应路径中创建的文件,但文件中没有数据。数据写入部分由接口方法完成。这是我需要帮助的部分。

提前致谢....

标签: javajunitmockito

解决方案


您正在将模拟注入ExtractCurrencyService到您的测试课程中。所以测试是使用这个模拟实例而不是ExtractCurrencyServiceImpl. 当前的行为是您的ExtractCurrencyDataTask测试类正在调用 to extractCurrencyService#extractCurrencyList,但这extractCurrencyService是一个模拟,而不是您的真实实现,因此调用已完成但它什么也不做。

如果你想进行单元测试ExtractCurrencyDataTask,那没关系,但也许你应该断言调用extractCurrencyService#extractCurrencyList是以你期望的方式完成的。

如果要进行单元ExtractCurrencyServiceImpl测试,请为此类创建单元测试。

如果你想测试这两个类之间的交互,那么创建一个集成测试,其中ExtractCurrencyDataTask注入了一个真实的实例ExtractCurrencyServiceImpl,而不是一个模拟。


推荐阅读