gpt4 book ai didi

java - 如何在没有过于复杂的代码的情况下为 Adapter 编写 JUnit?

转载 作者:搜寻专家 更新时间:2023-10-31 20:30:33 25 4
gpt4 key购买 nike

我有一个从 I1ILogger 的适配器,实现方式如下:

class BAdapter() implements I1
{
void logA() { // nothing }
void logB() { new BLogger().log() }
void logC() { // nothing }
}

我想编写 JUnit 测试来验证功能,但我发现它有点问题,因为我无法注入(inject)我的 Mock 对象而不是 BLogger,或验证返回值。我找到了几种可能的解决方案,但不确定哪个是最好的。

案例一:void setLogger(Logger l) 添加到 BAdapter 类。

class BAdapter() implements I1
{
private Logger logger = new BLogger();

public void logB() { logger.log() }
public void setLogger(Logger l) { logger = l }
.. //rest of methods
}

缺点:为什么要添加从未在“真实”、非测试代码中使用的 setter?

案例二:在测试包中添加 protected 工厂方法和子类BAdapter

class BAdapter() implements I1
{
public void logB() { createLogger().log() }
protected Logger createLogger() { retrun new BLogger() }
.. //rest of methods
}

class BAdapterForTesting extends BAdapter()
{
protected Logger createLogger() { retrun new MockBLogger() }
}

缺点:我不确定这是否是干净优雅的解决方案,但我看不出这里有太多缺点。

案例三:使用抽象工厂模式。

class BAdapter() implements I1
{
public void logB() { AbstractFactory.getFactory().getBLogger().log() }
.. //rest of methods
}

在测试的某处:

AbstractFactory.setFactory(new MockLoggersFactory())

缺点:这太复杂了,不是吗?

案例四:返回 boolean 值,例如,执行日志记录时。例如

class BAdapter() implements I1
{
Boolean logA() { return false; }
Boolean logB() { return new BLogger().log() }
Boolean logC() { return false; }
}

缺点:这是一种变通方法。为什么要返回一些值,当没有人在“真实的”非测试代码中需要它时?

更好的解决方案?有没有更好的?

最佳答案

从您的代码中很难准确判断被测类试图实现什么,但是我会选择案例一,但要注意我也会在“真实”代码中使用注入(inject)。

注入(inject)的好处之一是它使类(在本例中为您的适配器)更具可重用性。强制 logB 方法始终委托(delegate)给 BLogger 的实例,在编译时将这种行为固定下来。如果我希望适配器委托(delegate)给另一种类型的 Logger,我将无法使用它,因此它的可重用性稍差。

关于java - 如何在没有过于复杂的代码的情况下为 Adapter 编写 JUnit?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6860610/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com