I tried to test below class but got "org.mockito.exceptions.base.MockitoException: Only void methods can doNothing()!" and when i tried for Mocking i got nullpointerException.
@Configuration
@Profile("cloud")
public class PsqlConfiguration extends AbstractCloudConfig {
@Bean
public DataSource dataSource() {
return connectionFactory().dataSource();
}
}
Test written =>
@RunWith(MockitoJUnitRunner.class)
class PsqlConfiguration extends AbstractCloudConfig{
@Test
void dataSource() {
PsqlConfiguration ch = Mockito.spy(new PsqlConfiguration());
Mockito.doNothing().when((AbstractCloudConfig)ch).connectionFactory();
ch.dataSource();
}
Mock Test Written
@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
}
}
Judging from your test, I imagine you want to verify()
that your configuration's dataSource()
method is being called. If so, you probably want something like the following:
@Test
void dataSource() {
PsqlConfiguration ch = Mockito.spy(new PsqlConfiguration());
DataSource mockDs = Mockito.mock(DataSource.class);
Mockito.doReturn(mockDs).when(ch).dataSource();
}
The reason you are getting the error is that the AbstractCloudConfig
class's dataSource()
method returns a DataSource
, not void
. You can only use doNothing()
to mock void
methods.
If you really want to mock the superclass, you could do something like this:
@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();
}
Note however, that this test is meaningless as it is written. Your configuration class does not execute any code that is not from your framework (as far as you have written, and the configuration is loaded by Spring). Tests should only test your own code, not the underlying framework (which has its own tests).
I see by your comment:
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
That you're simply doing this for code coverage. This is not really a good practice, as:
Now, if your configuration source also did something with the dataSource
(aside from just retrieving it), you might write a test for that to assert that everything in your code uses it correctly. However, as written, it does not really help in any way.