伪装单元测试的构造函数

时间:2010-10-06 08:06:44

标签: java unit-testing design-patterns

我有一组在实例化时具有依赖关系的类,也就是说,在创建类型A的对象时,它还会创建另一个类型B,然后创建类型为C的其他类,等等。

对于测试问题,我不需要所有级别的全部功能来测试上层,所以我可以使用存根或模拟,但因为我在构造函数中有明确的new,所以我不能看到一个直接的方法,除了更改代码以使用AbstractFactory并提供一个在测试时创建假货。

那么,是否有任何“黑魔法”方法来破解Java类加载器,以便在使用new实例化对象时创建虚假测试类而不是正常测试类?

谢谢!

6 个答案:

答案 0 :(得分:6)

为什么不添加这些依赖项作为参数的构造函数,而不是在构造函数中自己创建它们?我个人会添加一个并删除另一个:)注入依赖项使代码更容易测试,将来更灵活(因为您可以在以后轻松注入不同的实现,而无需更改代码。)

答案 1 :(得分:2)

你想要的是使用模拟类。考虑使用任何框架。这是一个很好的 - https://jmockit.dev.java.net/

答案 2 :(得分:2)

您可以通过修改类路径来实现预期的行为,而无需修改原始源。在具有完全相同名称和包的第二个源文件夹中创建虚拟类。然后将虚拟类放到类路径中并删除真实类。

这适用于自己jar上的类,这样你就可以交换罐子。

答案 3 :(得分:1)

经过一些研究,似乎PowerMock可以做得很好:

http://code.google.com/p/powermock/wiki/MockConstructor

答案 4 :(得分:1)

JMockit完全符合要求。例如,您可以编写如下测试:

// In production code:
public final class ClassUnderTest
{
    private final SomeDependency dep;

    public ClassUnderTest(String someData)
    {
        dep = new SomeDependency(someData);
    }

    void methodToBeTested() { ... int i = dep.doSomething("xpto", true); ... }
}

final class SomeDependency
{
    int doSomething(String s, boolean b) { ... }
}

// In test code:
public final class MyTest
{
    @Test
    public void mockingInternalDependencies()
    {
        new Expectations()
        {
            SomeDependency mockedDep;

            {
                mockedDep.doSomething(anyString, anyBoolean); result = 123;
            }
        };

        new ClassUnderTest("blah blah").methodToBeTested();
    }
}

答案 5 :(得分:0)

另一种选择,正如我看到你不想创建构造函数,也不使用DI,可以拥有你需要使用默认可见性进行模拟的属性并创建工厂进行测试(使用相同的包和其他源文件夹) )直接注入模拟对象。