PowerMock whenNew Alternative

PowerMock whenNew Alternative

我不想再使用 powermock 了。因为 junit5 开始模拟静态 classes。所以我试图摆脱 powermock 方法。

如您所知,您可以使用 whenNew 关键字创建 class 的实例。

Junit5中有没有whenNew的替代方案?

这是我的部分代码:

                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));

根据 documentation,模拟对象构造自 Mockito 3.5.0 起可用。
首先,您需要将 mockito-inline 而不是 mockito-core 添加到您的测试依赖项中。
mockito-inline 提供模拟静态或最终方法、构造函数的能力。 Difference between mockito-core vs mockito-inline

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

让我们创建一个简单的服务来测试实例化对象。

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

带有注释的构造函数模拟示例:

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 ");
        }
    }
}

对于您的 类 示例:

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