简体   繁体   English

powermock mocking构造函数通过whennew()不能与匿名类一起使用

[英]powermock mocking constructor via whennew() does not work with anonymous class

I have a DummyResource class and a DummyTarget file, and a test class TestDummyResource as below, but the mocked object DummyResource dr = mock(DummyResource.class) only works when I call the constructor inside a normal class, when it's called in an anonymous class, it's calling the actual constructor instead of using the mocked object. 我有一个DummyResource类和一个DummyTarget文件,以及一个测试类TestDummyResource,如下所示,但是DummyResource dr = mock(DummyResource.class)对象DummyResource dr = mock(DummyResource.class)仅在我调用普通类中的构造函数时才有效,当它在匿名类中调用时,它调用实际的构造函数而不是使用模拟对象。

Versions: 版本:

powermock 1.4.12 mockito 1.9.0 junit 4.8.2 powermock 1.4.12 mockito 1.9.0 junit 4.8.2

DummyTarget.java: DummyTarget.java:

import java.io.IOException;
import java.io.OutputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;


public class DummyTarget {
    public StreamingOutput testMocking() {
        return new StreamingOutput() {
            @Override
            public void write(OutputStream arg0) throws IOException, WebApplicationException {
                new DummyResource();
            }
        };
    }
}

DummyResource.java: DummyResource.java:

package com.smin.dummy;

public class DummyResource {
    public DummyResource() {
        System.out.println("mock failure");
    }
}

TestDummyResource.java: TestDummyResource.java:

package com.smin.dummy;

import static org.mockito.Mockito.mock;

import java.io.IOException;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest({DummyResource.class,DummyTarget.class})
public class TestDummyResource  {

    @Before
    public void setUp() throws Exception {
        DummyResource dr = mock(DummyResource.class);
        PowerMockito.whenNew(DummyResource.class).withNoArguments().thenReturn(dr);
    }

    @Test
    public void testMocked() throws WebApplicationException, IOException {
        new DummyResource(); // it uses the mocked object dr here, 
                             //doesn't print "mock failure"
        StreamingOutput sop = new DummyTarget().testMocking();
        sop.write(null);     // it calls DummyResource's constructor,
                             // prints ""mock failure"" here
    }
}

You need to have prepared the class calling the constructor, not the class on which the constructor is called, the following should fix you up: 你需要准备调用构造函数的类,而不是调用构造函数的类,以下内容应该修复你:

@PrepareForTest(DummyTarget.class)

For more information check this page. 有关更多信息,请查看页面。

It looks like an anonymous class may inherit the package of the class that defines it. 看起来匿名类可能会继承定义它的类的包。 Can you try the wildcard form of PrepareForTest ?: 你可以尝试使用PrepareForTest的通配符吗?:

@PrepareForTest("com.smin.dummy.*")

If that doesn't work, you could try the shotgun PrepareEverythingForTest Annotation. 如果这不起作用,您可以尝试使用猎枪PrepareEverythingForTest Annotation。

Actually, you have to prepare for test the class that makes the constructor call, not the class on which the constructor was called. 实际上,您必须准备测试构造函数调用的类,而不是调用构造函数的类。 See https://github.com/jayway/powermock/wiki/MockConstructor . 请参阅https://github.com/jayway/powermock/wiki/MockConstructor

In your case, you should use @PrepareForTest(DummyTarget.class) 在您的情况下,您应该使用@PrepareForTest(DummyTarget.class)

I had the same problem, and resolved it with using whenNew with fully qualified name. 我遇到了同样的问题,并使用带有完全限定名称的whenNew解决了这个问题。 The fully qualified name of an inner anonymous class in your case is: 在您的情况下,内部匿名类的完全限定名称是:

DummyTarget.class + "$1"

so you should create a mock of that class: 所以你应该创建一个该类的模拟:

DummyResource dr = mock(Class.forName(DummyTarget.class + "$1"));

and it will work for you. 它会对你有用。

Also, don't forget to prepare the DummyTarget class: 另外,不要忘记准备DummyTarget类:

@PrepareForTest(DummyTarget.class)

Hope it helped =] 希望它有帮助=]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM