简体   繁体   中英

PowerMock whenNew Alternative

I don't want to use powermock anymore. Because junit5 started mocking static classes. So i am trying to get rid of powermock methods.

As you know, you can create an instance of a class with whenNew keyword.

Is there any alternative in Junit5 for whenNew?

Here is a part of my code:

                whenNew(PDFDocument.class).withNoArguments().thenReturn(pdfDocument);
                whenNew(PSConverter.class).withNoArguments().thenReturn(converter);
                doNothing().when(pdfDocument).load(ArgumentMatchers.any(ByteArrayInputStream.class));
                doAnswer(invocationOnMock -> {
                    ByteArrayOutputStream outputStream = invocationOnMock.getArgument(1);
                    outputStream.write(content);
                    return outputStream;
                }).when(converter).convert(ArgumentMatchers.any(), ArgumentMatchers.any(ByteArrayOutputStream.class));

Mocking object construction is available since Mockito 3.5.0 according to documentation .
First of all you need add the mockito-inline instead of the mockito-core to your test dependencies.
mockito-inline provides ability to mock static or final methods, constructors. Difference between mockito-core vs mockito-inline

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>${mockito.version}</version>
            <scope>test</scope>
        </dependency>

Let's create a simple service for testing which instantiate objects.

public class A {
    private final String test;

    public A(String test) {
        this.test = test;
    }

    public String check() {
        return "checked " + this.test;
    }
}

public class B {
    private String check = " B check ";

    public String check() {
        return check;
    }

}

public class TestService {
    public String purchaseProduct(String param) {
        A a = new A(param);
        B b = new B();
        return a.check() + b.check();
    }
}

Example of constructor mock with comments:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;

import static org.mockito.Mockito.when;

public class ConstructorMockTest {
    @Test
    public void test_mocked_construction()  {
        try (
             //create mock for object A
             MockedConstruction<A> mockedA = Mockito.mockConstruction(A.class,
                (mock, context) -> {
                    //set return value for object A mock methods
                    when(mock.check()).thenReturn(" Constructor Mock A ");
             });
             //create mock for object B
             MockedConstruction<B> mockedB = Mockito.mockConstruction(B.class,
                     (mock, context) -> {
                         //set return value for object B mock methods
                         when(mock.check()).thenReturn(" Constructor Mock B ");
             }))
        {
            // every A object creation is current try() scope returning a mock
            A aObject = new A("test");
            Assertions.assertEquals( aObject.check(), " Constructor Mock A ");

            // every B object creation is current try() scope returning a mock
            B bObject = new B();
            Assertions.assertEquals( bObject.check(), " Constructor Mock B ");

            //Example of testing service which creates A and B objects
            TestService service = new TestService();
            String serviceResult = service.purchaseProduct("test");

            Assertions.assertEquals(serviceResult, " Constructor Mock A  Constructor Mock B ");
        }
    }
}

For your classes example:

    @Test
    public void test() {
        byte[] content = new byte[] {1,1};

        try (
                MockedConstruction<PDFDocument> mockedPDFDocument = Mockito.mockConstruction(PDFDocument.class,
                        (mock, context) -> {
                            doNothing().when(mock).load(ArgumentMatchers.any(ByteArrayInputStream.class));
                        });

                MockedConstruction<PSConverter> mockedPSConverter = Mockito.mockConstruction(PSConverter.class,
                        (mock, context) -> {
                            doAnswer(invocationOnMock -> {
                                ByteArrayOutputStream outputStream = invocationOnMock.getArgument(1);
                                outputStream.write(content);
                                return outputStream;
                            }).when(mock).convert(ArgumentMatchers.any(), ArgumentMatchers.any(ByteArrayOutputStream.class));
                        }))
        {
            //call services which instantiates PDFDocument and PSConverter
            PDFDocument pdfDocument = new PDFDocument();
            PSConverter psConverter = new PSConverter();

            Assertions.assertTrue(org.mockito.internal.util.MockUtil.isMock(pdfDocument));
            Assertions.assertTrue(org.mockito.internal.util.MockUtil.isMock(psConverter));
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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