使用powermock抑制java中的单例构造函数

使用powermock抑制java中的单例构造函数,java,singleton,powermock,suppress,Java,Singleton,Powermock,Suppress,我正在尝试对一些类进行单元测试,这些类使用了一个单例类,它的构造函数做了一些我在单元测试环境中不能(也不应该)做的事情。我的理想场景是最终完全抑制构造函数,然后去掉测试类调用的其他成员方法。我的问题是,我似乎无法抑制构造函数 我对解决这一问题的方法的理解如下: public class MySingleton extends AbstractSingletonParent { public final static MySingleton Only = new MySingleton()

我正在尝试对一些类进行单元测试,这些类使用了一个单例类,它的构造函数做了一些我在单元测试环境中不能(也不应该)做的事情。我的理想场景是最终完全抑制构造函数,然后去掉测试类调用的其他成员方法。我的问题是,我似乎无法抑制构造函数

我对解决这一问题的方法的理解如下:

public class MySingleton extends AbstractSingletonParent {
    public final static MySingleton Only = new MySingleton();
    private MySingleton(){
        super(someVar); // I want the super-class constructor to not be called
        //
        //more code I want to avoid
    }

    public Object stubbedMethod() {}
}

public class ClassToBeTested {
    public void SomeMethod(){
        Object o = MySingleton.Only.stubbedMethod();
    }
}


@RunWith(PowerMockRunner.class)
@PrepareForTest(MySingleton.class)
public class TestClass {
    @Test
    public void SomeTest() {
        suppress(constructor(MySingleton.class));
        mockStatic(MySingleton.class);

        PowerMock.replay(MySingleton.class);
        // invoke ClassToBeTested, etc

        PowerMock.verify(MySingleton.class);

        //make some assertions
    }
}
不幸的是,在createMock调用期间,MySingleton构造函数被命中,它仍然调用超级构造函数

我在做傻事吗?我在网上发现一个例子几乎完全是这样做的,但它使用的是一个不推荐使用的suppressConstructor方法。尽管有人反对,我也试过了,但没有用

我想做的事可能吗?如果是,我做错了什么


*编辑后的版本现在可以使用了。

您需要用
@PrepareForTest
注释
TestClass
,这样它就有机会操作单例的字节码

此外,超类ctor抑制签名应该包括
somevar
的类;现在您只是在抑制默认的ctor

请参阅此处的a,并提供更多详细信息

FWIW,这对我有用:

@RunWith(PowerMockRunner.class)
@PrepareForTest({EvilBase.class, NicerSingleton.class})
public class TestEvil {

    @Test
    public void testEvil() {
        suppress(constructor(EvilBase.class));
        assertEquals(69, EvilBase.getInstance().theMethod());
    }

    @Test public void testNice() {
        suppress(constructor(EvilBase.class));
        suppress(constructor(NicerSingleton.class));
        assertEquals(42, NicerSingleton.getInstance().theMethod());
    }

}

我不确定你做错了什么。但在设计方面,我可以建议您研究依赖注入,即DI

为了使代码可测试,请使用DI。使用DI,您可以将singleton类作为构造函数参数传递给测试类。现在,既然您传递了一个参数,那么在您的测试用例中,您可以创建
AbstractSingleton
类的自定义实现,并且您的测试用例应该可以正常工作


使用DI,您的代码将变得更易于测试

如何使用使用您想要的构造函数实例化的实例来设置Singleton的实例字段(
代码中的“仅”
)(您可以使用反射API或API来完成所有这一切)


激励性的示例对此进行了讨论。

感谢您的建议,但这不是一个选项。此注释没有改变任何东西。我尝试使用ClassToBeTested.class和MySingleton.class,这两个选项似乎都没有以任何方式改变结果。@user1042480 PowerMock的哪个版本?使用PowerMock-easymock-1.4.10-full和easymock-3.1。Java1.6I已经对测试方法进行了一些修改,并且与您建议的注释相结合似乎已经达到了目的。注释肯定是问题的一部分,因此感谢您的帮助@user1042480顺便说一句,我不确定您是否需要同时抑制两个CTOR;我想如果你抑制了超类,基类就不会被调用。