使用powermock抑制java中的单例构造函数 [英] suppress a singleton constructor in java with powermock

查看:194
本文介绍了使用powermock抑制java中的单例构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对一些使用 Singleton 类的类进行单元测试,该类的构造函数做了一些我不能(也不应该)在单元测试环境中做的事情.我的理想情况是最终完全抑制构造函数,然后将我的测试类调用的其他成员方法存根.我的问题是我似乎无法抑制构造函数.

I'm trying to unit-test some classes that make use of a Singleton class whose constructor does some things I can't (and shouldn't) do from the unit-test environment. My ideal scenario would be to end up with the constructor completely suppressed and then stub out the other member methods that my test classes invoke. My problem is that I can't seem to get the constructor suppressed.

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

My understanding of a way to solve this would be something like the following:

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 构造函数,它仍然调用了超级构造函数.

Unfortunately during the createMock invocation, the MySingleton constructor is hit, and it still calls the super constructor.

我在做傻事吗?我在网上找到了一个几乎完全如此的例子,但它使用了一个不推荐使用的suppressConstructor 方法.尽管弃用了我也尝试过,但无济于事......

Am I doing something silly? I found an example on the web doing almost exactly this, but it was using a deprecated suppressConstructor method. Despite the deprecation I tried that, too, to no avail...

我正在尝试做的事情可能吗?如果是这样,我做错了什么?

Is what I'm trying to do possible? If so, what am I doing wrong?

*修改后的版本现在有效.

*Edited version now works.

推荐答案

您需要使用 @PrepareForTest 注释来注释 TestClass 以便它有机会操作字节码的单身人士.

You need to annotate TestClass with the @PrepareForTest annotation so it has a chance to manipulate the bytecode of the singletons.

另外,超类ctor supression签名应该包括somevar的类;现在你只是在抑制默认的ctor.

Also, the superclass ctor supression signature should include somevar's class; right now you're just suppressing the default ctor.

请参阅 @PrepareForTest API 文档. 这是一个 博客文章 以及更多详细信息.

See the @PrepareForTest API docs. Here's a blog post with some more details as well.

FWIW,它对我有用:

FWIW, it's working for me:

@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());
    }

}

这篇关于使用powermock抑制java中的单例构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆