java - 如何模拟 Class.forName 和 class.Constructor.newInstance()

标签 java unit-testing

我一直在 mock

clazz = Class.forName("Complete Class path") 
Object obj = clazz.Constructor().getInstance();

我在谷歌上搜索了一下,找到了一些链接,这些链接告诉我们如何使用 powermock 模拟静态方法。我尝试使用这些逻辑来模拟

Class.forName("完整类路径")

Object obj = clazz.Constructor().getInstance() 但一直面临错误。

at sun.reflect.GeneratedSerializationConstructorAccessor16.newInstance(Unknown Source) [junit]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) [junit] 
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:45) [junit]
at org.powermock.reflect.internal.WhiteboxImpl.newInstance(WhiteboxImpl.java:223) [junit]
at org.powermock.reflect.Whitebox.newInstance(Whitebox.java:139) [junit]
at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:64) [junit]
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:203) [junit]
at org.powermock.api.extension.listener.AnnotationEnabler.standardInject(AnnotationEnabler.java:106) [junit]
at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:54) [junit]
at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:90) [junit]
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:292) [junit]
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127) [junit]
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82) [junit]
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) [junit]
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87) [junit]
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) [junit]
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207) [junit]
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146) [junit]
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) [junit]
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) [junit]
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) [junit]
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122) [junit]
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106) [junit]
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)

最佳答案

我不认为模拟 Class 是个好主意,您应该重写代码以使其更易于测试。您应该将您的组件创建委托(delegate)给一个工厂,然后很容易模拟它。

这是您的工厂的样子:

public interface MyObjectFactory {
    MyObject create();
}

然后在需要创建这个对象的类中,添加工厂作为字段

public class MyClass {
    // The factory that will create my objects
    private MyObjectFactory factory;

    public void someMethod() {
        // Calls the factory to create my object 
        MyObject object = factory.create();
        ...
    }
}

完成后,您可以使用 Mockito模拟您的 MyObjectFactory 以提供您选择的 MyObject 实例。

那么测试用例将是:

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

    @Mock
    MyObjectFactory factory;
    @InjectMocks
    MyClass myClass = new MyClass();

    @Test
    public void testSomeMethod() {
        ...
        Mockito.when(factory.create()).thenReturn(myObject);
        // Call the method
        myClass.someMethod();
    }
}

关于java - 如何模拟 Class.forName 和 class.Constructor.newInstance(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39279255/

相关文章:

java - IDN.toASCII 协议(protocol)必须先删除吗?

javascript - 在 mocha-jsdom 中使用 jQuery 时如何修复 "ReferenceError: $ is not defined"?

java - 本地运行的 DynamoDb 的默认预配置吞吐量(读取和写入容量单位)是多少?

java - DistanceMatrix API 的回调函数

java - 从 JQuery (Webdriver) 制作数组

java - 如何在Java中修改两个类的对象?

unit-testing - 使用 Delta Lake 表运行 Pytest 时出错

unit-testing - 使用 Jest 和 Enzyme 测试 switch 语句

objective-c - iOS 单元测试 : Can't link to symbols in my Application target. 怎么了?

php - 单元测试 : Specific testing & Flow of Control