【问题标题】:PowerMockito mocking static class INSIDE enum?PowerMockito 模拟静态类 INSIDE 枚举?
【发布时间】:2018-09-13 18:58:44
【问题描述】:

我有一个枚举,它必须有一个用于 bean 注入的内部静态类。

我觉得我正面临模拟最困难的情况:枚举、静态类、静态字段、静态方法..

public enum Category{

    C1(Something(Constants.getFactory().createSomething(""))),
    C2(...);

    public static Constants {
        @Autowired
        private static Factory factory;

        public static Factory getFactory(){
            return factory;
        }
    }
}

而我使用 PowerMockito 的测试类是:

@RunWith(PowerMockRunner.class)
@PrepareForTest({Category.class,Category.Constants.class})
public class CategoryTests {

    @Before
    public void setUp() throws Exception {
        PowerMockito.mockStatic(Category.class);
        PowerMockito.mockStatic(Category.Constants.class);  

        //This simply testing mock didn't work             
        //PowerMockito.when(Category.Constants
        //                .getFactory()).thenReturn("123");


        //I tried to mock the inner field 'factory' and use it directly without a getter 
        //(with small changes in the original class)
        //But it didn't work either
        Factory factory = PowerMockito.mock(Factory.class);
        NewClass newClass = PowerMockito.mock(NewClass.class);
        PowerMockito.when(Factory.createSomething(anySring()))
                                         .thenReturn(newClass);

        Whitebox.setInternalState(
                 Category.Constants.class,"factory",Factory);


        //This is like the most common way to stub
        //It didn't work, so I believe the inner static class were never mocked
        PowerMockito.doReturn(factory).when(Category.Constants.class,
                                       "getFactory", anyString());
    }


    //I don't know if real test cases matter that much but I update to add it for reference.
    @Test(dataProvider = "Case1")
    public void testFromFilterType(final String testName, String input, final Category expected) {
        assertEquals(Category.doSomething(input), expected);
    }

    @DataProvider(name = "Case1")
    Object[][] fromFilterTypeCases() {
        return new Object[][] {
            { "C1", "input1", Category.C1 },
            { "C2", "input2", Category.C2 },
        };
    }
}
//Currently the tests got skipped because in class Category Constants.getFactory().createSomething(""), 
//where Constants.getFactory() returns null and mocking doesn't work.

起初我没有模拟 Enum,而只是模拟了静态内部类。经过大量搜索,我尝试了各种方式。设置似乎正确,但可能会错过一些技巧。有什么帮助吗?

【问题讨论】:

  • 我认为这些模拟是在枚举初始化之后执行的。如何在枚举初始化之前模拟方法?

标签: java junit mockito powermock powermockito


【解决方案1】:

有点猜测:Category.class 是您要测试的类。该类本身包含 nothing 应该需要模拟/准备。 所以:将这些部分放入您的代码中。即使它不会导致您当前的问题,我很确定当您稍后开始测试时它可能会产生各种不良后果。

除此之外,真正的答案是首先避免使用 PowerMock(ito)。您已经在使用@Autowired,这意味着您正在使用 DI 框架。大多数 DI 框架也有用于单元测试的钩子。因此,您应该尝试让 @Autowired 在您的测试设置中工作。

【讨论】:

  • 谢谢,我需要模拟的是枚举内部使用的 'Constants.getFactory().createSomething("")'。如何在不返回空值的情况下摆脱嘲笑?
猜你喜欢
  • 1970-01-01
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多