如何使用(Power)Mockito在类的初始化中模拟私有静态方法的静态调用?

时间:2017-08-03 12:40:32

标签: java mocking powermockito

我有一个奇怪的情况,这是一些糟糕的设计的结果,但它是我需要接受的事实。问题是它在模拟时遇到问题,因为有问题的方法在尝试查找构建机器上不存在的本地文件时会产生副作用。

这是这样的:

class BadDesignedClass {
    public static final Properies = loadProperties();
    private static Properties loadProperties() {
        // ... loads non-existent property file and crashes...
    }
}

我有问题要模拟这个,因为目前我提到了测试类中的类,它调用了真正的loadProperties(),这是在Mockito或PowerMockito进行任何模拟之前,这会导致错误抛出。

2 个答案:

答案 0 :(得分:1)

在不初始化的情况下加载类(详情可在this answer中找到)。然后不会调用loadProperties。这可以用。

来实现
Class<?> clazz = Thread.currentThread().getContextClassLoader()
    .loadClass("org.example.BadDesignedClass");

然后您可以将clazz传递给PowerMockito。

答案 1 :(得分:0)

要获得完整的解决方案,我将在这里向我展示我所做的一切,受到SpaceTrucker建议的启发:

首先 :在没有初始化的情况下加载类:

class Selects extends React.Component {

  constructor(props){
    super(props)
    this.state = {
      selected : [0, 1]
    }
  }

  changeHandler(option) {
    const newSelectedOptions = this.state.selected; // This will mutate the original state, consider using _.clone or something like that
    newSelectedOptions[option.id] = option.value;
    this.setState({
      selected: newSelectedOptions
    })
  }

  drawSelects(){
    let numberOfSelects = 3;
    let selects = [];
    for (let i = 0; i < numberOfSelects; i++) {
      selects.push(
        <Select
          id={i}
          value={options[this.state.selected[i]]}
          options={options}
          onChange={this.changeHandler.bind(this)}
          searchable={false}
          clearable={false}
        />
        )
    }
    return selects;
  }

  render(){
    return (
      <div>
        {this.drawSelects()}
      </div>
    )
  }
}

第二 :抑制造成所有问题的静态方法。

Class<?> clazz = Thread.currentThread().getContextClassLoader()
        .loadClass("org.example.BadDesignedClass");

第三次 :继续像往常一样模拟课程,因为PowerMockito.suppress(PowerMockito.method(clazz , "loadProperties")); 现在被取消了。

loadProperties()