Fer*_*roc 14 java junit mockito
一些示例代码首先......
枚举:
public enum TestEnum {
YES,
NO
}
Run Code Online (Sandbox Code Playgroud)
一些代码:
public static boolean WorkTheEnum(TestEnum theEnum) {
switch (theEnum) {
case YES:
return true;
case NO:
return false;
default:
// throws an exception here
}
}
Run Code Online (Sandbox Code Playgroud)
问题:
TestEnum是我从不同开发人员的不同代码导入的东西.所以它实际上可以改变.对于这种情况,我想要一个实际检查该非现有值的单元测试.但我根本不知道如何用Mockito和JUnit做到这一点.
这部分当然不起作用:
@Test(expected=Exception.class)
public void DoesNotExist_throwsException() throws Exception {
when(TestEnum.MAYBE).thenReturn(TestEnum.MAYBE);
WorkTheEnum(TestEnum.MAYBE);
}
Run Code Online (Sandbox Code Playgroud)
我发现了一个使用PowerMock的例子,但我无法与Mockito合作.
有任何想法吗?
怎么样简单:
Set<String> expected = new HashSet<> (Arrays.asList("YES", "NO"));
Set<String> actual = new HashSet<>();
for (TestEnum e : TestEnum.values()) actual.add(e.name());
assertEquals(expected, actual);
Run Code Online (Sandbox Code Playgroud)
(使用HashSet而不是ArrayList,因为顺序无关紧要)
基于@assylias的答案,我认为这是你能做到的最好的:
List<String> unknown = new ArrayList<>();
for (TestEnum e : TestEnum.values())
unknown.add(e.name());
unknown.removeAll(Arrays.asList("YES", "NO"));
if (unknown.isEmpty()) {
// Not possible to reach default case, do whatever you need to do
} else {
TestEnum notIncluded = TestEnum.valueOf(unknown.get(0));
workTheEnum(notIncluded);
}
Run Code Online (Sandbox Code Playgroud)
由于switch语句的编译方式,不可能(AFAIK)伪造语句中不存在的enum值.即使您通过反射来摆弄实例中的内部字段,该陈述也将给出一个而不是落到案例中.switchenumordinalenumswitchArrayIndexOutOfBoundsExceptiondefault
以下是一些看似可能有用的代码,但由于ArrayIndexOutOfBoundsException上面提到的原因,它没有:
TestEnum abused = TestEnum.YES;
try {
Class<?> c = abused.getClass().getSuperclass();
Field[] declaredFields = c.getDeclaredFields();
Field ordinalField = null;
for (Field e : declaredFields) {
if (e.getName().equals("ordinal")) {
ordinalField = e;
}
}
ordinalField.setAccessible(true);
ordinalField.setInt(abused, TestEnum.values().length);
workTheEnum(abused);
} catch (Exception e) {
e.printStackTrace(System.err);
}
Run Code Online (Sandbox Code Playgroud)
好的,这可能适合你.它非常hacky,所以对我而言,可能比没有100%代码覆盖率,YMMV更糟糕.它的工作原理是将枚举序数查找数组替换为包含全零的数组,这些数组将落入默认情况.
// Setup values - needs to be called so that
// $SWITCH_TABLE$FooClass$BarEnum is initialised.
workTheEnum(TestEnum.YES);
workTheEnum(TestEnum.NO);
// This is the class with the switch statement in it.
Class<?> c = ClassWithSwitchStatement.class;
// Find and change fields.
Map<Field, int[]> changedFields = new HashMap<>();
Field[] declaredFields = c.getDeclaredFields();
try {
for (Field f : declaredFields) {
if (f.getName().startsWith("$SWITCH_TABLE$")) {
f.setAccessible(true);
int[] table = (int[])f.get(null);
f.set(null, new int[table.length]);
changedFields.put(f, table);
}
}
workTheEnum(TestEnum.YES);
} finally {
for (Map.Entry<Field, int[]> entry : changedFields.entrySet()) {
try {
entry.getKey().set(null, entry.getValue());
} catch (Exception ex) {
ex.printStackTrace(System.err);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11986 次 |
| 最近记录: |