【问题标题】:How to Mock HikariDataSource and DataSourceProperties?如何模拟 HikariDataSource 和 DataSourceProperties?
【发布时间】:2021-10-11 06:33:09
【问题描述】:

如何使用 springboot 和 Junit5 和 Mockito 模拟 HikariDataSource 和 DataSourceProperties? 我找到了一种可能的解决方案,但测试单一方法似乎是相当冗长的方法,您可以查看here 我正在尝试对我的班级中的一种“ping”方法进行单元测试,但出现异常:

java.lang.NullPointerException
    at com.my.app.configuration.DbConfigurationTest.shouldReturnPing(DbConfgiurationTest.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:532)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:171)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    

测试类:

import com.my.app.config.DbConfiguration;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.test.context.TestConfiguration;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.when;

@TestConfiguration
class DbConfigurationTest
{
 @InjectMocks static DbConfiguration dbConfiguration;


     DataSourceProperties dataSourceProperties= Mockito.mock(DataSourceProperties.class);


    @Test
    public void shouldReturnPing()
    {
        // expect
        boolean expectedResult = true;
        when(dbConfiguration.dataSourceProperties()).thenReturn(dataSourceProperties);
when(dbConfiguration.dataSource(dataSourceProperties).isRunning()).thenReturn(true);
        boolean actualResult = dbConfiguration.ping();

        assertThat(actualResult, is(equalTo(expectedResult)));
    }


}

需要测试的方法类:

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * Database configuration.  Only properties override is required, everything else comes from spring boot auto-config.
 */
@Configuration
public class DbConfiguration
{

    /**
     * Overrides the auto-configured bean in order to specify a different prefix for the DataSourceProperties
     *
     * @return A DataSourceProperties bean
     */
    @Bean
    @Primary
    @ConfigurationProperties("my.datasource")
    public DataSourceProperties dataSourceProperties()
    {
        return new DataSourceProperties();
    }

    /**
     * Overrides the {@link javax.sql.DataSource} bean creation from
     * {@link org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration}
     * to specify a different prefix for the {@link org.springframework.boot.context.properties.ConfigurationProperties}
     *
     * @param dataSourceProperties The properties to configure the datasource
     * @return A {@link com.zaxxer.hikari.HikariDataSource} instance
     */
    @Bean
    @ConfigurationProperties("my.datasource.configuration")
    public HikariDataSource dataSource(final DataSourceProperties dataSourceProperties)
    {
        return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }


    /**
     * Ping the service.
     *
     * @return the boolean
     */
    public boolean ping()
    {
        return dataSource(dataSourceProperties()).isRunning();
    }
}

如何成功测试“ping”方法?我试图创建模拟但失败了。 在此先感谢:)

【问题讨论】:

    标签: spring-boot junit mocking datasource hikaricp


    【解决方案1】:

    我建议将ping() 方法移到一个单独的类中并在那里自动装配DataSource。例如:

    @Component
    public class DatabaseHealthCheck {
        public DatabaseHealthCheck(HikariDataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        public boolean ping() {
            return dataSource.isRunning();
        }
    }
    

    现在你可以像这样测试它:

    // Mock only the DataSource, either with @Mock or like this
    HikariDataSource dataSource = mock(HikariDataSource.class);
    DatabaseHealthCheck healthCheck = new DatabaseHealthCheck(dataSource);
    when(dataSource.isRunning()).thenReturn(true);
    assertThat(healthCheck.ping()).isTrue();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-11
      • 2017-01-14
      • 2016-06-09
      • 1970-01-01
      • 2020-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多