可以模拟System.identityHashCode吗?

时间:2019-02-12 18:14:24

标签: java testing mocking

美好的一天。

我有一个工具,通过在每个项目中添加某些由字节码生成的toString实现来检测项目中的对象。生成的toString的逻辑无关紧要,但是重要的是它的返回值取决于内部进行的System.identityHashCode调用。

现在,我想用自动化测试介绍生成的逻辑。我创建了一个用于测试的类,为其生成了toString,并希望对其toString的输出进行断言。显然,这种测试是不可重现的,因为System.identityHashCode在两次测试之间得出的结果不同。

是否有可能模拟System.identityHashCode或稳定给出的结果?

2 个答案:

答案 0 :(得分:2)

可以使用Powermock进行此操作,如下所述:How to Mock System.getProperty using Mockito

但是,更好的方法是创建一个包装System的类,然后将包装器注入要测试的类中。

然后在单元测试中,您可以注入包装程序的测试实现并控制System的输出。

答案 1 :(得分:0)

我将介绍一个测试接缝:

@Override public String toString() {
  return toString(System.identityHashCode(object));
}

/** Visible for testing. */
String toString(int hashCode) {
  // Your implementation here.
}

这样,您可以根据需要从相邻测试中多次调用toString(int),而不必担心PowerMock甚至Mockito。

或者,如果System.identityHashCode在类的其他地方使用,则结果需要保持一致,则可以在构造函数中替换ToIntFunction,并使用默认的实现过程System.identityHashCode作为reference to a static method

public YourWrapperClass(Object object) {
  this(object, System::identityHashCode);
}

/** Visible for testing. */
YourWrapperClass(Object object, ToIntFunction<Object> hashCodeFunction) {
  this.object = object;
  this.hashCodeFunction = hashCodeFunction;
}