Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 向测试类动态添加JUnit测试_Java_Junit_Junit4 - Fatal编程技术网

Java 向测试类动态添加JUnit测试

Java 向测试类动态添加JUnit测试,java,junit,junit4,Java,Junit,Junit4,我发现自己这些天写了很多很多锅炉板测试,我想以一种干净的方式优化掉很多这些基本测试,这些测试可以不费吹灰之力地添加到所有当前的测试类中 下面是一个基本的测试类: class MyClassTest { @Test public void doesWhatItDoes() { assertEquals("foo",new MyClass("bar").get()); } } 假设MyClass实现了Serializable,那么我们需要确保它确实是可序

我发现自己这些天写了很多很多锅炉板测试,我想以一种干净的方式优化掉很多这些基本测试,这些测试可以不费吹灰之力地添加到所有当前的测试类中

下面是一个基本的测试类:

class MyClassTest {

    @Test
    public void doesWhatItDoes() {
        assertEquals("foo",new MyClass("bar").get());
    }

}
假设MyClass实现了Serializable,那么我们需要确保它确实是可序列化的。因此,我构建了一个类,您可以对其进行扩展,该类包含一组标准测试,这些测试将与其他测试一起运行

我的问题是,例如,如果MyClass没有实现Serializable,那么类中仍然有一个序列化测试。我们可以让它在不可序列化的类中成功,但它仍然停留在测试列表中,一旦这个类开始构建,它就会变得越来越混乱

我想做的是找到一种方法,在适当的地方动态添加那些与现有测试类相关的测试。我知道有些测试可以通过一套测试服来完成,但是你必须为每个类维护两个测试类,这很快就会成为一个麻烦

如果有人知道一种不需要eclipse插件之类的东西的方法,我将永远感激

编辑:添加了我上面描述的简要示例

class MyClassTest extend AutoTest<MyClass> {

    public MyClassTest() {
        super(MyClass.class);
    }

    @Test
    public void doesWhatItDoes() {
        assertEquals("foo",new MyClass("bar").get());
    }

}

public abstract class AutoTest<T> {
    private final Class<T> clazz;
    protected AutoTest(Clazz<T> clazz) {
        super();
        this.clazz = clazz;
    }

    @Test
    public void serializes() {
        if (Arrays.asList(clazz.getInterfaces()).contains(Serializable.class)) {
        /* Serialize and deserialize and check equals, hashcode and other things... */
        }
    }
}
class MyClassTest扩展自动测试{
公共MyClassTest(){
超级(MyClass.class);
}
@试验
public void doesWhatItDoes(){
assertEquals(“foo”,新的MyClass(“bar”).get();
}
}
公共抽象类自动测试{
私人期末班;
受保护的自动测试(Clazz-Clazz){
超级();
this.clazz=clazz;
}
@试验
public void序列化(){
if(Arrays.asList(clazz.getInterfaces()).contains(Serializable.class)){
/*序列化、反序列化并检查equals、hashcode和其他内容*/
}
}
}

JUnit现有功能中最实用的解决方案是使用一个带注释的测试:

@Test
void followsStandardJavaLibraryProtocols() {
    if (implementsInterface(Serializable.class) {
         testSerialisableInterface       

...
打破了TDD的各种抽象原则,但有效,没有不必要的聪明

也许,Junit可以扩展为对这种带有子测试的体系结构测试有更直接的支持,而不是简单的测试用例列表。类似于@Subtest注释的东西,它标识了一个不被直接调用的测试,而是在该测试被调用时将一个节点添加到结果树中,并使用什么参数

两个想法

想法1: 使用
假设

一组用于说明关于测试有意义的条件的假设的方法。失败的假设并不意味着代码被破坏,而是测试没有提供有用的信息。默认的JUnit运行程序将忽略假设失败的测试

想法2:实施您自己的测试运行程序


看看
@RunWith
Runner
at

我觉得你的方法很有效。我没有问题

我的做法略有不同。我将创建另一个测试来测试所有可序列化类:

public class SerializablesTest {
    @Test
    public void serializes() {
        testSerializable(MyClass.class);
        testSerializable(MyClass2.class);
    }

    private testSerializable(Class clazz) {
        // do the real test here
        /* Serialize and deserialize and check equals, hashcode and other things... */
    }
}
这给了你什么?对我来说,明确性。我知道我正在测试类MyClass的可序列化性。这里面没有魔法。你不需要污染你的其他测试

如果您确实需要测试所有实现可序列化的类,那么可以使用反射找到所有类


我经常使用这种方法,使用反射来构建对象。例如,我可以测试所有字段是否被正确地持久化并从数据库中重新读取。我一直在使用这种东西。

您确定要单元测试实现可序列化的类是否真的可序列化吗?或者这仅仅是一个例子?是的,但是我还想测试其他一些东西,比如可空性,以及使用jsr-305注释。这在很大程度上是受Guavas测试框架的启发,但它仍然需要大量的锅炉板,我认为我们应该能够避免。IMHO,单元测试应该只关注被测试的类。如果您的对象未正确编组,功能/集成测试将捕获它。@Sahil是否确实要等到集成测试运行后才能检测此类错误?根据我的经验,这类事情确实会捕获bug,并允许您安全地重构。这太棒了,我可以用我的方法解决所有令人讨厌的问题,并且仍然保持良好的可管理性,谢谢!
public class SerializablesTest {
    @Test
    public void serializes() {
        testSerializable(MyClass.class);
        testSerializable(MyClass2.class);
    }

    private testSerializable(Class clazz) {
        // do the real test here
        /* Serialize and deserialize and check equals, hashcode and other things... */
    }
}