23

我有一个 DummyResource 类和一个 DummyTarget 文件,以及一个测试类 TestDummyResource,如下所示,但是模拟对象DummyResource dr = mock(DummyResource.class)仅在我在普通类中调用构造函数时才有效,当在匿名类中调用它时,它调用的是实际构造函数而不是使用模拟对象。

版本:

powermock 1.4.12 mockito 1.9.0 junit 4.8.2

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:

package com.smin.dummy;

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

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
    }
}
4

4 回答 4

39

您需要准备好调用构造函数的类,而不是调用构造函数的类,以下应该可以解决您的问题:

@PrepareForTest(DummyTarget.class)

有关更多信息,请查看页面。

于 2012-11-20T20:41:27.333 回答
17

看起来匿名类可能会继承定义它的类的包。你可以试试PrepareForTest? 的通配符形式:

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

如果这不起作用,您可以尝试 shotgun PrepareEverythingForTestAnnotation。

于 2012-11-20T21:20:05.483 回答
10

实际上,您必须准备测试调用构造函数的类,而不是调用构造函数的类。请参阅https://github.com/jayway/powermock/wiki/MockConstructor

在您的情况下,您应该使用 @PrepareForTest(DummyTarget.class)

于 2014-02-14T18:02:37.213 回答
0

我遇到了同样的问题,并通过使用带有完全限定名称的 whenNew 来解决它。在您的情况下,内部匿名类的完全限定名称是:

DummyTarget.class + "$1"

所以你应该创建一个该类的模拟:

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

它会为你工作。

另外,不要忘记准备 DummyTarget 类:

@PrepareForTest(DummyTarget.class)

希望它有所帮助=]

于 2016-03-04T19:17:17.680 回答