gpt4 book ai didi

java - 被测单元 : Impl or Interface?

转载 作者:IT老高 更新时间:2023-10-28 21:08:57 26 4
gpt4 key购买 nike

假设我有实现它的接口(interface)和实现类,我想为此编写单元测试。我应该测试什么接口(interface)或Impl?

这是一个例子:

public interface HelloInterface {
public void sayHello();
}


public class HelloInterfaceImpl implements HelloInterface {
private PrintStream target = System.out;


@Override
public void sayHello() {
target.print("Hello World");

}

public void setTarget(PrintStream target){
this.target = target;
}
}

所以,我有实现它的 HelloInterface 和 HelloInterfaceImpl。什么是被测单元接口(interface)或 Impl?

我觉得应该是HelloInterface。考虑下面的 JUnit 测试草图:

public class HelloInterfaceTest {
private HelloInterface hi;

@Before
public void setUp() {
hi = new HelloInterfaceImpl();
}

@Test
public void testDefaultBehaviourEndsNormally() {
hi.sayHello();
// no NullPointerException here
}

@Test
public void testCheckHelloWorld() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintStream target = new PrintStream(out);
PrivilegedAccessor.setValue(hi, "target", target);
//You can use ReflectionTestUtils in place of PrivilegedAccessor
//really it is DI
//((HelloInterfaceImpl)hi).setTarget(target);
hi.sayHello();
String result = out.toString();
assertEquals("Hello World", result);

}
}

主线实际上是我注释掉的。

((HelloInterfaceImpl)hi).setTarget(target);

方法 setTarget() 不是我的公共(public)接口(interface)的一部分,所以我不想不小心 调用它。如果我真的想调用它,我应该花点时间考虑一下。例如,它帮助我发现我真正想做的是依赖注入(inject)。它为我打开了整个世界的新机遇。我可以使用一些现有的依赖注入(inject)机制(例如 Spring 的),我可以自己模拟它,就像我在代码中实际所做的那样,或者采用完全不同的方法。仔细看,准备 PrintSream 没那么容易,也许我应该改用 mock 对象?

编辑:我认为我应该始终关注界面。从我的角度来看, setTarget() 也不是 impl 类的“契约(Contract)”的一部分,它为依赖注入(inject)服务。我认为从测试的角度来看,任何 Impl 类的公共(public)方法都应该被认为是私有(private)的。但这并不意味着我忽略了实现细节。

另见 Should Private/Protected methods be under unit test?

EDIT-2 在多个实现\多个接口(interface)的情况下,我会测试所有的实现,但是当我在 setUp() 方法中声明一个变量时我肯定会使用界面。

最佳答案

实现是需要测试的单元。这当然是您要实例化的内容以及包含程序/业务逻辑的内容。

如果您有一个关键接口(interface),并且希望确保每个实现都正确地遵守它,那么您可以编写一个专注于接口(interface)并要求传入实例的测试套件(与任何实现类型无关)。

是的,将 Mockito 用于 PrintStream 可能会更容易,但可能并不总是可以避免像在此特定示例中那样使用模拟对象。

关于java - 被测单元 : Impl or Interface?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10937763/

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