请帮助编写Junit接口默认方法。
public interface ABC<T, D, K, V> {
default List<String> getSrc(DEF def, XYZ xyz) throws Exception {
}
}
ABC:接口名称。 DEF和XYZ:类名
答案 0 :(得分:3)
正如答案中所建议的,为界面创建实现类并对其进行测试,对于我在vmax
界面中修改getSrc
方法的示例,如下所示:< / p>
ABC
为此创建了一个实现类,可选地,您可以创建另一个调用super方法的方法,并为两者编写import java.util.ArrayList;
import java.util.List;
public interface ABC<T, D, K, V> {
default List<String> getSrc(DEF def, XYZ xyz) {
final List<String> defaultList = new ArrayList<>();
defaultList.add("default");
defaultList.add("another-default");
return defaultList;
}
}
,如下所示:
@Test
实施的对应测试类如下:
import java.util.List;
public class ABCImpl implements ABC<String, Integer, String, Integer> {
public List<String> getSrcImpl(DEF def, XYZ xyz) {
final List<String> list = getSrc(def, xyz);
list.add("implementation");
return list;
}
}
答案 1 :(得分:3)
我认为有一种更简单的方法。 它包括使用要在测试类中测试的方法来实现接口,并直接调用默认类型的方法。如有必要,将对内部调用的对象进行模拟。前面的示例如下:
接口)
public interface ABC<T, D, K, V> {
default List<String> getSrc(DEF def, XYZ xyz) throws Exception {
list<String>() result=new Arraylist<String>();
result.add(def.toString());
result.add(xyz.toString());
return result;
}
}
测试类)
...
@RunWith(MockitoJUnitRunner.class)
public class ABCTest implements ABC{
@Test
public void testGetSrc() {
list<String>() result=getSrc(new DEF("Hi!"),new XYZ("bye!"));
int actual=result.size();
int expected=2;
assertEquals(expected, actual);
}
如果您需要测试异常的启动,就足以迫使其从错误的参数中释放并正确配置测试:
...
@Test(expected = GenericRuntimeException.class)
public void test....
...
我已经用类似的代码对其进行了检查,并且可以正常工作。也可以在覆盖率分析中正确收集它。
答案 2 :(得分:1)
您可以创建一个实现您的界面的类,也可以让您的测试实现它。第二个似乎是一个较短的解决方案:
public class FunctionCallingTransactionTemplateTest implements FunctionCallingTransactionTemplate {
private final Object object = Mockito.mock(Object.class);
@Test
public void should_invoke_function() throws Exception {
// given
when(object.toString()).thenReturn("salami");
// when
String result = functionCallingTransactionTemplate().execute((status) -> object.toString());
// then
assertThat(result).isEqualTo("salami");
}
}
答案 3 :(得分:1)
如果您使用的是Mockito,则对默认方法(又称“防御者”)进行单元测试的最简单方法是使用界面制作spy
1 类literal 2 。然后可以像往常一样在返回的间谍实例上调用默认方法。以下示例演示:
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.spy;
interface OddInterface {
// does not need any unit tests because there is no default implementation
boolean doSomethingOdd(int i);
// this should have unit tests because it has a default implementation
default boolean isOdd(int i) {
return i % 2 == 1;
}
}
public class OddInterfaceTest {
OddInterface cut = spy(OddInterface.class);
@Test
public void two_IS_NOT_odd() {
assertFalse(cut.isOdd(2));
}
@Test
public void three_IS_odd() {
assertTrue(cut.isOdd(3));
}
}
(已通过Java 8和mockito-2.24.5测试)
1 人们经常警告使用spy
可以表示代码或测试气味,但是测试默认方法是使用{{1 }}是一个好想法。
2 在撰写本文时(2019年),接受类文字的spy
的签名被标记为spy
,但已经自mockito-1.10.12于2014年发布以来一直存在。此外,support for default methods in Mockito自mockito-2.1.0于2016年发布以来一直存在。可以肯定的是,该方法将来会继续有效版本的Mockito。
答案 4 :(得分:0)
答案很简单。无需嘲笑或暗中监视,只需为接口创建一个匿名对象而无需覆盖默认方法即可。
例如:
interface Adder {
default sum(Integer...n) {
return Arrays.stream(n).reduce(0, Integer::sum);
}
}
// Junit 4
class AdderTest {
private Adder adder;
@Before
public void setup() {}
adder = new Adder(){}; // not overriding default methods
}
@Test
public void testSum() {
Assert.assertEquals(3, adder.sum(1, 2));
}
}