Spring Boot测试无需数据库连接。

huangapple go评论71阅读模式
英文:

Spring boot test without database connection

问题

首先,我在我的测试类上面加了以下注解:

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = Application.class)
    @AutoConfigureMockMvc

使用这个配置会尝试连接我的数据库,如果我的数据库没有运行,就会出现以下错误:

    com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

    The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

我希望我的测试在没有任何数据库连接的情况下运行,所以我尝试更改了注解,现在我的测试类看起来像这样:

    @RunWith(SpringRunner.class)
    @DataJpaTest
    @WebMvcTest(CitizenController.class)
    @AutoConfigureMockMvc
    public class CitizenControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private CitizenRepository citizenRepository;

    @MockBean
    private WeeklyCareRepository weeklyCareRepository;

    @MockBean
    private SubCategoryCareRepository subCategoryCareRepository;

    @Autowired
    private ObjectMapper objectMapper;

    private static List<Citizen> mockCitizenList;

    private String citizenJson;

然而,现在我又遇到了另一个错误:

    java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [controllers.CitizenControllerTest]: [@org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.context.SpringBootTestContextBootstrapper), @org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper)]

是否可能在没有数据库连接的情况下运行我的测试?如果可能,我做错或者遗漏了什么?
英文:

At first I had the following annotation above my test class:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@AutoConfigureMockMvc

With that configuration it tries to connect to my database, which will give me this error if my database is not running:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

I would like my test to run without any connection to a database, which is why I tried to change the annotations, so my test class now looks like this:

@RunWith(SpringRunner.class)
@DataJpaTest
@WebMvcTest(CitizenController.class)
@AutoConfigureMockMvc
public class CitizenControllerTest {

@Autowired
private MockMvc mockMvc;

@MockBean
private CitizenRepository citizenRepository;

@MockBean
private WeeklyCareRepository weeklyCareRepository;

@MockBean
private SubCategoryCareRepository subCategoryCareRepository;

@Autowired
private ObjectMapper objectMapper;

private static List&lt;Citizen&gt; mockCitizenList;

private String citizenJson;

However, I am now getting another error:

java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [controllers.CitizenControllerTest]: [@org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.context.SpringBootTestContextBootstrapper), @org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper)]

Is it possible to run my test without a database connection? If so, what am I doing wrong/missing?

答案1

得分: 8

你可以在 @Test 方法中的存储库类中模拟将连接到数据库的方法。

@SpringBootTest
@AutoConfigureMockMvc
class StoreApplicationTests {

    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private CitizenRepository citizenRepository;
    
    
    @Test
    void contextLoads() {
    }
    
    @Test
    public void test() {
        
        Mockito.when(citizenRepository.getDataFromDB()).thenReturn("Something you'd like to Return");
        
    }

}

这样做之后,当调用 citizenRepository.getDataFromDB() 时,将不会连接到数据库。


根据您的评论后更新:

然后您只需创建 "src/test/resources" 目录,将应用程序的 application.properties 或 application.yml 从 "src/main/resources" 复制到该目录,并注释掉 MySQL 连接部分。

如果您没有 "src/test/resources/application.properties",那么Spring默认会读取 "src/main/resources/application.properties" 并根据该文件配置项目,由于文件中有数据源配置,Spring 将尝试连接到数据库,如果数据库服务器关闭,您将会收到连接失败的消息。

英文:

You can just mock the method that will connect to database in your repository class in the @Test method.

@SpringBootTest
@AutoConfigureMockMvc
class StoreApplicationTests {

	@Autowired
	private MockMvc mockMvc;
	
	@MockBean
	private CitizenRepository citizenRepository;
	
	
	@Test
	void contextLoads() {
	}
	
	@Test
	public void test() {
		
		Mockito.when(citizenRepository.getDataFromDB()).thenReturn(&quot;Something you&#39;d like to Return&quot;);
		
	}

}

After doing that, citizenRepository.getDataFromDB() will not connect to database when it's called.


Update After Your Comment:

Then you can just create "src/test/resources" and copy your application.properties or application.yml from "src/main/resources" to that directory and comment the mysql connection part.

If you don't have "src/test/resources/application.properties", then spring will read "src/main/resources/application.properties" by default and configure the project according to that file, since you have datasource configuration in it, spring will try to connect to the database, if database server is down, you would get the failure.

huangapple
  • 本文由 发表于 2020年4月11日 08:48:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/61150735.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定