如何测试何时调用超类方法?
How to test when Superclass method is called?
我尝试在 class 下面进行测试,但得到了“org.mockito.exceptions.base.MockitoException:
只有 void 方法可以 doNothing()!" 当我尝试模拟时我得到了 nullpointerException。
@Configuration
@Profile("cloud")
public class PsqlConfiguration extends AbstractCloudConfig {
@Bean
public DataSource dataSource() {
return connectionFactory().dataSource();
}
}
测试已写=>
@RunWith(MockitoJUnitRunner.class)
class PsqlConfiguration extends AbstractCloudConfig{
@Test
void dataSource() {
PsqlConfiguration ch = Mockito.spy(new PsqlConfiguration());
Mockito.doNothing().when((AbstractCloudConfig)ch).connectionFactory();
ch.dataSource();
}
已完成模拟测试
@RunWith(MockitoJUnitRunner.class)
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
}
}
从您的测试来看,我想您想要 verify()
调用配置的 dataSource()
方法。如果是这样,您可能需要如下内容:
@Test
void dataSource() {
PsqlConfiguration ch = Mockito.spy(new PsqlConfiguration());
DataSource mockDs = Mockito.mock(DataSource.class);
Mockito.doReturn(mockDs).when(ch).dataSource();
}
您收到错误的原因是 AbstractCloudConfig
class 的 dataSource()
方法 returns 和 DataSource
,而不是 void
.您只能使用 doNothing()
模拟 void
方法。
如果你真的想要模拟超级class,你可以这样做:
@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();
}
但是请注意,这个测试在编写时毫无意义。您的配置 class 不会执行任何不是来自您的框架的代码(就您编写的而言,配置由 Spring 加载)。测试应该只测试你自己的代码,而不是底层框架(它有自己的测试)。
看到你的评论:
If i directly mock child class method then it works but code coverage is 0 percent so i thought to mock " connectionFactory().dataSource()" . So that it gives 100 percent code coverage, But it gives NullPointerException
您这样做只是为了代码覆盖率。这不是一个好的做法,因为:
- 你正在膨胀代码库来为不在你的代码责任范围内的东西编写测试。
- 100% 的覆盖率并不意味着代码库没有错误。
现在,如果您的配置源 也 对 dataSource
做了一些事情(除了检索它),您可能会为此编写一个测试来断言所有内容在您的代码中正确使用它。然而,正如所写的那样,它并没有任何帮助。
我尝试在 class 下面进行测试,但得到了“org.mockito.exceptions.base.MockitoException: 只有 void 方法可以 doNothing()!" 当我尝试模拟时我得到了 nullpointerException。
@Configuration
@Profile("cloud")
public class PsqlConfiguration extends AbstractCloudConfig {
@Bean
public DataSource dataSource() {
return connectionFactory().dataSource();
}
}
测试已写=>
@RunWith(MockitoJUnitRunner.class)
class PsqlConfiguration extends AbstractCloudConfig{
@Test
void dataSource() {
PsqlConfiguration ch = Mockito.spy(new PsqlConfiguration());
Mockito.doNothing().when((AbstractCloudConfig)ch).connectionFactory();
ch.dataSource();
}
已完成模拟测试
@RunWith(MockitoJUnitRunner.class)
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
}
}
从您的测试来看,我想您想要 verify()
调用配置的 dataSource()
方法。如果是这样,您可能需要如下内容:
@Test
void dataSource() {
PsqlConfiguration ch = Mockito.spy(new PsqlConfiguration());
DataSource mockDs = Mockito.mock(DataSource.class);
Mockito.doReturn(mockDs).when(ch).dataSource();
}
您收到错误的原因是 AbstractCloudConfig
class 的 dataSource()
方法 returns 和 DataSource
,而不是 void
.您只能使用 doNothing()
模拟 void
方法。
如果你真的想要模拟超级class,你可以这样做:
@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();
}
但是请注意,这个测试在编写时毫无意义。您的配置 class 不会执行任何不是来自您的框架的代码(就您编写的而言,配置由 Spring 加载)。测试应该只测试你自己的代码,而不是底层框架(它有自己的测试)。
看到你的评论:
If i directly mock child class method then it works but code coverage is 0 percent so i thought to mock " connectionFactory().dataSource()" . So that it gives 100 percent code coverage, But it gives NullPointerException
您这样做只是为了代码覆盖率。这不是一个好的做法,因为:
- 你正在膨胀代码库来为不在你的代码责任范围内的东西编写测试。
- 100% 的覆盖率并不意味着代码库没有错误。
现在,如果您的配置源 也 对 dataSource
做了一些事情(除了检索它),您可能会为此编写一个测试来断言所有内容在您的代码中正确使用它。然而,正如所写的那样,它并没有任何帮助。