如何为方法参数中具有私有枚举的方法编写JUnit测试用例

时间:2016-01-28 17:48:54

标签: java junit mockito

我有一个Spring Controller类,它定义了一个接受私有枚举的方法,如下所示。我们如何使用Junit / Mockito为此编写测试用例?

@RequestMapping("/getData")
public String getData(
            @RequestParam(value = "someFilter") SomeFilter someFilter)
             {
                // do something
}

在上面的代码中,SomeFilter是一个enum,被定义为私有内部类。

在为上述方法编写测试用例时,由于enum不可见,我无法调用该方法,我尝试使用Mockito.any(),仍然没用。

我们有没有办法测试上述方法?

2 个答案:

答案 0 :(得分:1)

因此,如果该方法将被spring调用,那么你必须找出,如何并复制它。但老实说,它仍然闻起来像可怕的糟糕代码,一种实际上并不公开的公共方法......

无论如何,你当然可以通过一些反思魔法测试它......让我们假设这个简单的类......

public class Testy {

    private enum TestyEnum {
        X,
        y;
    }

    public String someMethod(final TestyEnum testyEnum) {
        return testyEnum.name();
    }

}

因此,我们有一个私有枚举和一个公共方法,接受它作为参数。要调用它,我们必须使用反射......

public class TestyTest {

    private final Testy toTest = new Testy();

    @Test
    public void someMethod_should_return_correct_name_of_x() throws Exception {

        // Get the class object for our private enum
        final Class<?> testyEnumClass = Class.forName( "de.assona.iframe.view.Testy$TestyEnum" );

        // List the enum constants
        final Object[] consts = testyEnumClass.getEnumConstants();

        // Get the method via reflection per name and argument type
        final Method method = Testy.class.getMethod( "someMethod", testyEnumClass );

        // call (invoke) it...
        final Object o = method.invoke( this.toTest, consts[0] );

        // And check that the object returned is actually the correct String we expect the name of the private enum constant)
        Assert.assertEquals( "X", o );

    }
}

但是,当然,这是一个可怕的解决方法,阅读不好,维护不好以及解决您不应该遇到的问题。 Spring不要求你生成错误的代码,相反,它解决了导致代码错误的许多问题。所以我会真的建议您尝试重构该代码,使其以清晰,易于维护的方式进行测试。相信我,你(和你的同行代码)不会对你找到一种测试不良代码的方法感到高兴,因为这会让你保留那些糟糕的代码。经过测试的坏代码比未经测试的坏代码更好,但仍然很糟糕。从长远来看,你(以及你的同行代码)会有更好的代码,因为它使一切变得更加容易......

答案 1 :(得分:0)

您可以使用Spring MockMvc测试代码,而不是调用控制器对象的方法。

public class ControllerTest {
  private final YourController controller = ...
  private final MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller)
      .build();

  @Test
  public void someTest() throws Exception {
     mockMvc.perform(get("/getData").param("someFilter", "THE_NAME_OF_THE_FILTER"))
       .andExpect(status().isOk())
       .andExpect(content().mimeType("text/html"))
       .andExpect(...);
  }
}