测试包装类

时间:2015-11-26 17:03:38

标签: java unit-testing mocking mockito

我想测试一个用作包装器的类,它为下面的类提供抽象。

这意味着我需要在该类中创建一些对象,也就是说,我不通过构造函数或某种方法传递协作者。

例如,这是一个包装类:

public class Abstraction {

      private ComplexClass complex;

      public class Abstraction(some parameters) {
           complex = new Complex(parameters);
      }

}

为了能够测试这个类,我有一个想法,就是创建一个返回Complex类对象的方法,如下所示:

public class Abstraction {

      private ComplexClass complex;

      public class Abstraction(parameters) {
           complex = createComplex(parameters);
      }

      protected createComplex ComplexClass(parameters) {
           return new ComplexClass(parameters);
      }
}

问题是,我不能使用Mockito来模拟我正在测试的类构造函数中创建的协作者。如何克服这个?

我的想法是窥探SUT以便createComplex返回模拟对象,但我不能这样做,因为需要先创建SUT。这是一种死锁。

我的最终目标是测试是否调用了一些协作者类的方法。

4 个答案:

答案 0 :(得分:2)

测试此课程的业务优势是什么?它没有实现算法,也没有做出决定。如你所说,它只是一个包装。

你说你想测试某些方法是否被调用但这对任何人有何帮助?当然,测试确认在某些情况下调用这些方法而不是其他情况,换句话说是对业务逻辑的测试,将会更加有用。这里存在的风险是,您将最终进行难以维护的复杂测试,并引入惯性,这将使未来的重新分解变得更加困难和昂贵。你希望有什么奖励能让这种风险变得有价值?

答案 1 :(得分:1)

你可以在测试用例

中使用一个相当简单的匿名内部类来完成它
ComplexClass mock = Mockito.mock(ComplexClass.class);
Abstraction abstraction = new Abstraction("foo") {
    @Override
    protected ComplexClass createComplex(parameters) {
       return mock;
    }
};
assertTrue("bar", abstraction.doStuff());

答案 2 :(得分:1)

您可以为ComplexClass上设置的Abstraction实施factory

public class ComplexClassFactory {
    public ComplexClass create(parameters) {
        return new ComplexClass(parameters);
    }
}

public class Abstraction {

    private ComplexClassFactory complexClassFactory; 

    public void setComplexClassFactory(ComplexClassFactory complexClassFactory) {
        this.complexClassFactory = complexClassFactory;
    }

    private ComplexClass complex;

    public class Abstraction(parameters) {
       complex = complexClassFactory.create(parameters);
    }
}

答案 3 :(得分:1)

一种可能性是为ComplexClass类(我命名为Complex)提取一个接口,并提供一个替代构造函数,仅用于测试目的注入一个实例新创建的Complex接口:

    public class Abstraction {

        private Complex complex;

        public Abstraction(String parameters) {
            this.complex = new ComplexClass(parameters);
        }

        Abstraction(Complex complex) {
            this.complex = complex;
        }

        public class ComplexClass implements Complex {

            private final String parameters;

            public ComplexClass(String parameters) {
                this.parameters = parameters;
            }
        }

        interface Complex {
        }

    }

这样你可以为Complex接口创建一个模拟器,使用接收Complex实例的构造函数并独立测试 Abstraction 类:

@Test
public void testAbstraction() {
    Complex mock = Mockito.mock(Complex.class);
    Abstraction abstraction = new Abstraction(mock);
}