Java 如何为方法参数中包含私有枚举的方法编写JUnit testcase
我有一个Spring控制器类,它定义了一个接受私有枚举的方法,如下所示。我们如何使用Junit/Mockito为此编写测试用例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
@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(...);
}
}