Java 单元测试尝试使用空指针的方法

Java 单元测试尝试使用空指针的方法,java,spring,nullpointerexception,mockito,Java,Spring,Nullpointerexception,Mockito,我正在测试一种类似于以下内容的方法: car.driveCar("carName", problematicMethod().getBrand()); problematicMethod()是处理安全上下文的单例。通常,problematicMethod()不会返回空指针,但在单元测试中,它会返回空指针。我无法更改该方法的源代码,并且由于其设计原因,无法使用Mockito对其进行模拟driveCar()不返回任何内容 我尝试了以下方法,以查看它是否会完全抑制对该行的求值: Mockito.do

我正在测试一种类似于以下内容的方法:

car.driveCar("carName", problematicMethod().getBrand());
problematicMethod()
是处理安全上下文的单例。通常,
problematicMethod()
不会返回空指针,但在单元测试中,它会返回空指针。我无法更改该方法的源代码,并且由于其设计原因,无法使用Mockito对其进行模拟<代码>driveCar()不返回任何内容

我尝试了以下方法,以查看它是否会完全抑制对该行的求值:

Mockito.doNothing().when(car).driveCar(Mockito.eq("carName"), Mockito.any());
但它仍然给我一个Nullpointer异常,因为它试图计算第二个参数。

您将“problematicMethod()”描述为一个单例。方法不是单例。类可以是单例的

我认为您要说的是,这个类实现了多个您无法分离的关注点,因此您必须在模拟其他方法的同时测试一些方法


假设这是真的,你将不得不在Mockito中使用“间谍”的概念。阅读有关间谍的Mockito文档。这会使你的考试更混乱,更难理解,但你已经在课堂上做到了这一点。:)

Mockito无法解决您的问题:

   car.driveCar("carName", problematicMethod().getBrand());
// [1] [5]      [2]        [3]                 [4]
Java保证调用
problematicMethod()
将在调用
driveCar
之前发生,因此模拟
driveCar
不会阻止调用
problematicMethod
。虽然您知道Mockito会导致调用
driveCar
时什么也不做,但是Java运行时无法知道这一点


您可以尝试重构对
problematicMethod().getBrand()
的调用,然后针对覆盖或Mockito间谍进行测试:

public class YourClass {
  public ReturnType yourMethod() {
    car.driveCar("carName", getBrand());
  }

  /** Gets brand via problematicMethod(). Package private for test overrides. */
  Brand getBrand() {
    return problematicMethod().getBrand();
  }
}

(请注意,此技术也可以应用于整个
driveCar
方法调用,如果有足够的实现,您可以将其提取到自己的对象中。)

为什么
problematicMethod()
无法模拟?为什么在单元测试中它返回
null
?也许您可以模拟该方法所依赖的内容,以便它在单元测试中不返回null。它是处理安全上下文的单例。“它是处理安全上下文的单例。”这是一个非常重要的细节,应该在问题描述中提及。如果因为无法注入模拟而无法对其进行模拟,则可能需要重新思考您的体系结构。如果它包含静态方法,请将PowerMockito与Mockito.post edited结合使用。我不能改变架构或引入新的库,所以我想这不会是一个简单的方法。我必须找到另一种方法来进行测试,但我仍然会接受这个答案。