Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何为方法参数中包含私有枚举的方法编写JUnit testcase_Java_Junit_Mockito - Fatal编程技术网

Java 如何为方法参数中包含私有枚举的方法编写JUnit testcase

Java 如何为方法参数中包含私有枚举的方法编写JUnit testcase,java,junit,mockito,Java,Junit,Mockito,我有一个Spring控制器类,它定义了一个接受私有枚举的方法,如下所示。我们如何使用Junit/Mockito为此编写测试用例 @RequestMapping("/getData") public String getData( @RequestParam(value = "someFilter") SomeFilter someFilter) { // do something } 在上面的代码中,SomeFi

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

@RequestMapping("/getData")
public String getData(
            @RequestParam(value = "someFilter") SomeFilter someFilter)
             {
                // do something
}
在上面的代码中,SomeFilter是一个枚举,它被定义为类内的私有

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


我们有什么方法来测试上述方法吗?

因此,如果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 );

    }
}
公共类TestyTest{
private final Testy toTest=new Testy();
@试验
public void someMethod\u应该\u返回\u正确的\u名称\u of \u x()抛出异常{
//获取私有枚举的类对象
最终类testyEnumClass=Class.forName(“de.assona.iframe.view.Testy$TestyEnum”);
//列出枚举常量
最终对象[]常量=testyEnumClass.getEnumConstants();
//通过每个名称和参数类型的反射获取方法
final-Method=Testy.class.getMethod(“someMethod”,TestyNumClass);
//调用(调用)它。。。
final Object o=method.invoke(this.toTest,consts[0]);
//并检查返回的对象是否为正确的字符串(我们希望是私有枚举常量的名称)
Assert.assertEquals(“X”,o);
}
}

但当然,这是一个可怕的解决方法,不好阅读,不好维护,是一个你不应该有的问题的解决方案。Spring不要求您生成错误代码,相反,它解决了许多导致错误代码的问题。因此,我想真的建议您尝试重构代码,使其以清晰、易于维护的方式可测试。相信我,你(和你的代码伙伴)不会因为找到了测试坏代码的方法而感到高兴,因为这会让你保留坏代码。经过测试的坏代码比未经测试的坏代码好,但仍然是坏代码。从长远来看,使用好的代码,您(和您的代码伙伴)会更快乐,因为它使一切变得更容易……

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


如果无法从外部访问SomeFilter,该类如何正常调用?如果无法从外部访问,为什么该方法是公共的?当然,您可以通过反射访问枚举,但整个过程闻起来像是坏代码,需要尽快重构。@FlorianSchaetz很棒的答案,为什么不将其发布为答案?这是一个Spring方法,因此在调用URL时Spring将调用它。我不确定spring如何在内部映射它。我觉得enum应该是公共的。这将更好地反映它的实际使用情况。你说不能更改代码是什么意思?为什么要测试不能更改的代码;如果测试发现代码中有bug,你会怎么做?
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(...);
  }
}