java - 如何调用抽象类的私有(private)构造函数进行模拟。

标签 java unit-testing reflection easymock powermock

我在如何正确测试这段代码方面遇到了一些问题。我希望能够使用 Mocking 框架或通过反射来模拟对 delegateForFoo 的调用。但是,当我尝试通过反射或 PowerMock 执行此操作时,出现如下代码所示的错误。

@Test
public void testDelegatedMethodWithPowerMock() throws Exception {

    DelegateForFoo mockedDelegateForFoo = PowerMock
            .createMock(DelegateForFoo.class);

    Foo foo = Whitebox.invokeConstructor(Foo.class, mockedDelegateForFoo);
    // org.powermock.reflect.exceptions.ConstructorNotFoundException: Failed
    // to find a constructor with parameter types: at line above.

    Constructor<Foo> fooConstructor = Foo.class
            .getDeclaredConstructor(DelegateForFoo.class);
    fooConstructor.setAccessible(true);
    Foo foo2 = fooConstructor.newInstance(mockedDelegateForFoo);
    // java.lang.InstantiationException at line above.

}

我已尽力检查以前的 stackOverflow 问题,但没有看到直接解决此问题的问题。有一些关于如何调用具体类的私有(private)构造函数的答案,还有一些关于如何在抽象类上对私有(private)方法进行分类的答案,但没有关于这个特定实例的答案。

我的正式问题如下:有没有办法调用抽象类的私有(private)构造函数并传入模拟对象以进行测试。

我知道通常你不应该测试私有(private)方法等。但是在这种情况下,我想测试一个有正当理由成为私有(private)的构造函数。 Bar 根本没有理由知道委托(delegate)的任何信息,为了适当封装,它应该是私有(private)的。提前致谢。

我正在使用的代码如下。

public abstract class Foo {

    private DelegateForFoo delegateForFoo;
    private int valueToBeSetFromDelegate;

    Foo() {
        // I don't want the subclasses to do anything with this DelegateForFoo.
        // It's set through the constructor because there is a requirement that
        // Foo must have a delegateForFoo in order to be created.
        this(new DelegateForFoo());
    }

    // This Constructor is indirectly called by the subclasses. They don't know
    // anything about how it is set, or what it does.
    private Foo(DelegateForFoo delegateForFoo) {
        this.delegateForFoo = delegateForFoo;
        this.valueToBeSetFromDelegate = this.delegateForFoo.delegatedMethod();
    }

    int useTheDelegateForSomeMethod() {
        return this.delegateForFoo.delegatedMethod();
    }
}


public class DelegateForFoo {
    int delegatedMethod() {
        return 5;
    }
}



public class Bar extends Foo {
    // here, Bar doesn't care about the delegate for Foo at all. It only cares
    // that the method it is called has some implementation.
    int useDelegateForFooWithoutKnowingAboutIt() {
        return super.useTheDelegateForSomeMethod() + 10;
    }
}

最佳答案

您不能创建Foo 类实例的原因是因为它是抽象。 Java 中没有可以创建抽象类实例的机制。

要测试抽象类,您需要定义将扩展 Foo 的新类。这意味着将调用默认构造函数。

关于java - 如何调用抽象类的私有(private)构造函数进行模拟。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24922588/

相关文章:

java - 为什么Android中不保留Intent

java - Java 类对象是唯一的/单例的吗?

regex - Grails 域类单元测试,约束设置问题 - java.lang.NoClassDefFoundError : Could not initialize

Java 超接口(interface)运行时差异 Java 8 与 Java 9

java - 类路径上的资源是否有与 Files.newDirectoryStream 等效的文件

java - ant:警告:编码 UTF8 的不可映射字符

java - 如何在 Maven 中使用 junit 运行配置文件特定的测试用例?

c# - XUnit 如何模拟 IMemoryCache ASP.NET Core

c# - 如何在 C# 中使用反射调用将字符串数组作为参数的方法

java - 使用反射可以使集合(列表)的大小小于 0 吗?