Java 如何测试调用超类方法的时间?

Java 如何测试调用超类方法的时间?,java,junit5,spring-boot-test,Java,Junit5,Spring Boot Test,我试图在下面的类中进行测试,但得到了“org.mockito.exceptions.base.MockitoException: 只有void方法不能执行任何操作()!“当我尝试模拟时,得到了nullpointerException @配置 @个人资料(“云”) 公共类PsqlConfiguration扩展了AbstractCloudConfig{ @豆子 公共数据源数据源(){ 返回connectionFactory().dataSource(); } } 笔试=> @RunWith(Moc

我试图在下面的类中进行测试,但得到了“org.mockito.exceptions.base.MockitoException: 只有void方法不能执行任何操作()!“当我尝试模拟时,得到了nullpointerException

@配置
@个人资料(“云”)
公共类PsqlConfiguration扩展了AbstractCloudConfig{
@豆子
公共数据源数据源(){
返回connectionFactory().dataSource();
}
}
笔试=>

@RunWith(MockitoJUnitRunner.class)
类PsqlConfiguration扩展了AbstractCloudConfig{
@试验
void数据源(){
PsqlConfiguration ch=Mockito.spy(新的PsqlConfiguration());
Mockito.doNothing().when((AbstractCloudConfig)ch.connectionFactory();
ch.dataSource();
}
模拟笔试

@RunWith(MockitoJUnitRunner.class)

类PsqlConfigurationTest{

@InjectMocks
PsqlConfiguration psqlConfiguration = new PsqlConfiguration();

AbstractCloudConfig config = Mockito.mock(AbstractCloudConfig.class);

@Test
void dataSource() {
    DataSource dataSource = Mockito.mock(DataSource.class);
    Cloud cloud = Mockito.mock(Cloud.class);
    ServiceConnectionFactory factory = new CloudServiceConnectionFactory(cloud);
    Mockito.when(config.connectionFactory()).thenReturn(factory);
    System.out.println(config.connectionFactory());
    Mockito.when(config.connectionFactory().dataSource()).thenReturn(dataSource);
    assertNull(psqlConfiguration.dataSource()); // This gives null

}

}

从您的测试判断,我想您希望
验证()
您的配置的
数据源()
方法正在被调用。如果是这样,您可能需要以下内容:

@Test
void dataSource() {
    PsqlConfiguration ch = Mockito.spy(new PsqlConfiguration());
    DataSource mockDs = Mockito.mock(DataSource.class);
    Mockito.doReturn(mockDs).when(ch).dataSource();
}
出现错误的原因是
AbstractCloudConfig
类的
dataSource()
方法返回一个
dataSource
,而不是
void
。您只能使用
doNothing()
来模拟
void
方法

如果你真的想模仿超类,你可以这样做:

@Test
void dataSource() {
    PsqlConfiguration ch = Mockito.spy(new PsqlConfiguration());
    DataSource mockDs = Mockito.mock(DataSource.class);
    ConnectionFactory mockFactory = Mockito.mock(ConnectionFactory.class);
    Mockito.doReturn(mockDs).when(ch).dataSource();
    Mockito.doReturn(mockFactory).when((AbstractCloudConfig)ch).connectionFactory();
    ch.dataSource();
    verify(ch).connectionFactory();
}
但是,请注意,此测试在编写时毫无意义。您的配置类不会执行任何非来自框架的代码(就您编写的情况而言,配置是由Spring加载的)。测试应该只测试您自己的代码,而不是底层框架(它有自己的测试)


我从你的评论中看到:

若我直接模拟子类方法,那个么它可以工作,但代码覆盖率为0%,所以我想模拟“connectionFactory().dataSource()”。所以它提供100%的代码覆盖率,但它提供NullPointerException

您这样做只是为了代码覆盖率。这并不是一个好的实践,因为:

  • 您正在膨胀代码库,以便为不属于代码职责范围的内容编写测试
  • 100%的覆盖率并不意味着代码库没有bug

  • 现在,如果您的配置源还对
    数据源
    执行了一些操作(除了检索它之外),您可以为此编写一个测试来断言代码中的所有内容都正确地使用了它。但是,正如编写的那样,它在任何方面都没有真正的帮助。

    为什么?为什么您甚至要为您的配置编写一个测试并模拟它?无论如何,
    doNothing
    意味着它不会返回任何内容,并且该方法显然应该返回一些内容。所以您可能想要返回模拟或间谍:我尝试了模拟,但它给出了Nullpointer异常。我知道普通模拟,但它对超级类的工作方式相同吗?您可以添加此测试的目的吗?您到底想测试什么?我看不到任何与超级类相关的内容你好,如果我直接模拟子类方法,那么它可以工作,但是代码覆盖率是0%,所以我想嘲笑“连接因子”(.DATA)(因此它给出了100%个代码覆盖率,但是它给出了Null PoExExvice异常,谢谢您的建议,只会进行简单的测试。很高兴听到它有帮助。如果您的问题得到解决,请考虑接受答案。