powermock mocking constructor via whennew() does n

2019-01-26 03:28发布

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.

Versions:

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条回答
时光不老,我们不散
2楼-- · 2019-01-26 04:08

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.

查看更多
乱世女痞
3楼-- · 2019-01-26 04:26

I had the same problem, and resolved it with using whenNew with fully qualified name. 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:

@PrepareForTest(DummyTarget.class)

Hope it helped =]

查看更多
该账号已被封号
4楼-- · 2019-01-26 04:32

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.

In your case, you should use @PrepareForTest(DummyTarget.class)

查看更多
We Are One
5楼-- · 2019-01-26 04:34

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("com.smin.dummy.*")

If that doesn't work, you could try the shotgun PrepareEverythingForTest Annotation.

查看更多
登录 后发表回答