Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Mockito in spring to solve the problem of Bean dependency Tree

2025-02-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces how to use Mockito in spring to solve the Bean dependency tree problem, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let Xiaobian take you to understand.

Premise

Basic Concepts Junit initialization and existing problems

When spring applications are in unit test, test runs independently, so you need to init ApplicationContext and launch the Ioc container.

Junit requires that all Spring bean injections involved in the Test class succeed to complete applicationContext initialization and start the IOC container, otherwise unit test cannot be executed.

Two ways of ApplicationContext initialization: manual injection (using @ Bean or @ Component injection of required classes) Writing @ Configuration classes (using @ ComponentScan to specify scan beans) problems with two initialization methods

Method 1:

In the required beans, if a bean is not injected, it will cause too many beans to be injected into the context, which will take a lot of time and effort, and it is difficult to troubleshoot the omissions.

Method 2:

The granularity is difficult to control. As the project size becomes larger, it may lead to too many bean imports, and unit testing takes a long time to pass. When the project scale is large, the dependence between bean is often complex. The way to scan bean may have some unknown problems that do not belong to your own modules or some middleware cannot start properly in the unitTest environment, resulting in unable to initialize the context what is the dependency tree?

When developing an application, there are often tree dependencies like the figure above, such as serviceA calling serviceB,serviceB and serviceC.

However, this is only a simple example. In real development, a service often relies on multiple service and multiple dao to implement business logic.

According to the Junit requirements, we must inject all the nodes (bean) that the path of the tree passes through to complete the spring context initialization. At this point, if the dependency coupling between bean is too large, you can't get rid of the problems caused by the two initialization methods.

What is Mockito?

During testing, for some objects that are not easy to construct (such as HttpServletRequest must be constructed in a Servlet container) or more complex objects that are not easy to obtain (such as ResultSet objects in JDBC), use a virtual object (Mock object) to create test methods for testing.

The biggest function of Mock is to help you decouple the unit test. If your code is dependent on another class or interface, it can help you simulate these dependencies and help you verify the behavior of the dependencies you are calling.

To put it simply: it is a virtual mock object, which will "change the prince" during the unit test, replace the original bean, "fool" spring initialization, and successfully start the ioc container, so as to avoid all kinds of problems caused by conventional initialization.

Development scenario

Combined with the problems I encountered in my work, when I wrote the module for unitTest, there was the problem that the dependency tree was too large.

First of all, I used the regular manual injection (method 1), so that the injection was not finished for a long time and the test could not be performed. Later, I felt that this method was not feasible in this situation. Then, I used to write the @ Configuration class (method two), but there were also some problems. Some bean that are not part of my module are also injected, and some of the bean involving TaskSchedule cannot be injected correctly, causing the test not to be executed. At this time one by one bean exploration, to solve the problem is obviously not realistic. Finally, I use the combination of Junit+Mockito for unit testing. Distinguish according to the size of the dependency tree. The dependency tree is small and directly uses conventional manual injection (method 1), which saves trouble, and at the same time ensures that most of the logic runs normally according to the code and relies on the large use of Mockito to avoid the problems caused by the two initialization methods mentioned above.

Import maven dependencies using 1

First import mockito maven dependencies. Please select the version according to your own spring version, otherwise there will be incompatibility.

Org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine junit junit 4.12 test

Note:

Spring-boot-starter-test was imported here because the dependency already contains the mockito-related jar package

Spring-boot-starter-test can use @ MockBean annotations (mockito-core, mockito-all seem to be unable)

The difference between @ Mock and @ MockBean:

@ Mock

@ MockBean mock bean replacement time after completion of spring context initialization, whether the spring context initialization can be "cheated" during the execution of spring context initialization No is it possible to solve the problem whether the dependency tree does not work properly when all the required bean is injected and cannot complete spring context initialization @ MockBean replaces when initializing, and the bean detected during spring context initialization is the replaced mock bean On the other hand, mock bean itself does not depend on any other bean, so it can naturally "trick" through the spring context initialization phase and successfully launch IOC Container 2 to analyze the dependencies between bean.

Use a simple Demo to simulate the development scenario, use the combination of Junit+Mockito for unit testing, and distinguish whether or not mock is needed according to the size of the dependency tree.

As shown in the figure, here you write a ControllerA,ControllerA that relies on two bean:ServiceA,DaoA

Analysis process: about DaoA: since Dao tends not to rely on other bean, you can use regular manual injection here (method 1). About ServiceA: because serviceA depends on serviceB (- > DaoB) and serviceC (- > DaoC), nested dependent bean like this can use Mockito to solve the dependency tree problem. 3 write Test classes

DaoA can be injected with @ Bean annotations

@ Bean public DaoA daoA () {return new DaoAImpl ();}

1.serviceA first uses the @ MockBean annotation to simulate serviceA as MockBean, which will replace the original Bean when the spring context is initialized

@ MockBean private ServiceA serviceA

two。 Before the test class executes (@ Before), use Mockito API to set the return value of calling a method (the result you expect), and the specified value will be returned when the method is called in the Test class

@ Before public void init () {MockitoAnnotations.initMocks (this); / / the sentence when (controllerA.serviceA_method ()) .thenReturn ("666") can be omitted when only @ MockBean is used;}

3. Use @ InjectMocks to notify the controllerA that depends on the serviceA. When the spring starts, the bean of controllerA will be post-processed accordingly.

@ Autowired @ InjectMocks private ControllerA controller

4. When unit testing, you will not use the original Bean method, but instead use Mock Bean and its methods that have specified the return value

@ Test public void testDeepMock () {String s = controllerA.serviceA_method (); System.out.println (s);}

5.unitTest result

Thank you for reading this article carefully. I hope the article "how to use Mockito in spring to solve the Bean dependency tree problem" shared by the editor will be helpful to everyone. At the same time, I also hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report