In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
SpringBoot unit test using @ Test no run method is the solution, I believe that many inexperienced people do not know what to do, so this article summarizes the causes of the problem and solutions, through this article I hope you can solve this problem.
SpringBoot unit tests use @ Test without the run method
Rebuilding the test class found @ Test useful again, only to find that it was because the default Tests test class did not have the public keyword!
This mistake was corrected for two hours.
= follow up: = =
Found the reason.
The default is 2.3.0 when building a project, so the default created class structure should be version 2.3.0.
Org.springframework.boot spring-boot-starter-parent 2.3.0.RELEASE
Emmm . Previously, because it was changed to 2.1.7.RELEASE, the structure of the project was different due to different versions.
Now go back to 2.3.0RELEASE
You can run normally. And there is no @ RunWith annotation.
SpringBoot writes the pit encountered in the unit test
Recently, the project needs to write unit tests. The project I started was written in SpringBoot. So I simply studied how to use it. I encountered a lot of problems in use, so I had to write test cases in a different way, and I didn't feel very good after writing it. Today, I learned a new usage on the official website of Spring and found that there was no problem with this test method. So let's take some notes.
How to write unit test by SpringBoot
SpringBoot provides annotations to write unit tests, and you can use SpringBootTest annotations to mark test classes.
@ RunWith (SpringRunner.class) @ SpringBootTestpublic class SpringBootTest {@ Testpublic void method () {}}
Writing in this way can only solve the test logic without some configuration files, such as no database configuration, database connection pool configuration, and so on. If you have these configurations, you need to write like this.
@ RunWith (SpringRunner.class) @ SpringBootTest (classes = Application.class) @ Testpublic void method () {}
So it can work properly.
Test the controller class. Using Mock, the following method is mostly circulated on the Internet, adding @ WebAppConfiguration and using MockMvc for unit testing, but there is a problem with the following use of my project. I can't find the Controller class when I execute it, and all kinds of methods on Baidu online don't work. Will report a no bean of 'controller' type found error.
@ RunWith (SpringRunner.class) @ SpringBootTest (classes = Application.class) @ WebAppConfiguration public class ControllerTest {private MockMvc mockMvc; @ Autowired private WebApplicationContext wac; @ Before / / initialize the work public void setup () {this.mockMvc = MockMvcBuilders.webAppContextSetup (this.wac). Build () before the test starts. } @ Test public void getMessageTest () throws Exception {MvcResult mvcResult = mockMvc.perform (MockMvcRequestBuilders.get ("/ test/getMessage")) .andDo (MockMvcResultHandlers.print ()) .andReturn (); int status = mvcResult.getResponse () .getStatus (); String content = mvcResult.getResponse () .getContentAsString (); Assert.assertTrue ("success", status = = 200); Assert.assertFalse ("failed", status! = 200) System.out.println ("content" + content);}
Later, I changed the way to directly new a controller. The no bean of 'controller' type found error is not reported after the test is run, but the service used in controller reports a null pointer exception NPE, and the transitivity is obvious. Controller is an object of new, so the annotation does not work, and service is null.
Finally, simple unit testing can be achieved by using @ AutoConfigureMockMvc+@MockBean without affecting the data and the database.
@ RunWith (SpringRunner.class) @ SpringBootTest (classes = Application.class) @ AutoConfigureMockMvcpublic class ImkfMessageReportControllerTest {/ * initialize MockMvc * / @ Autowired private MockMvc mvc; / * controller * / @ MockBean private UserController userController for testing @ Test public void getUserListTest () throws Exception {MvcResult mvcResult = mvc.perform (MockMvcRequestBuilders.get ("/ user/getUserList")) .andexpect (MockMvcResultMatchers.status (). IsOk ()) .andDo (MockMvcResultHandlers.print ()) .andReturn (); String content = mvcResult.getResponse () .getContentAsString (); System.out.println ("content" + content) } SpringBoot uses Mockito for unit testing
The above is the use of MockMvc, although it can verify the correctness of short links and even service code logic, and can properly test interface problems. But there are also many disadvantages, for example, coverage has not increased. Mockito is a very useful unit testing tool. Its implementation principle is that it inherits the class to be Mock and overrides all public methods.
@ RunWith (MockitoJUnitRunner.class) public class UserServiceTest {@ Mock private UserMapper userMapper; @ InjectMocks private UserService userService; @ Test public void saveTest () throws Exception {User user = new User (); user.setUserName (Long.valueOf ("springBoot")); when (userMapper.insert (user)) .thenReturn (user); int num = userService.save (user); Assert.assertEquals ("success", 1,1);}}
Use RunwWith (MockitoJUnitRunner.class) (you can also use SpringBootRunner.class) for mocktio testing. Note @ Mock to mark a class or interface that needs to be mock, which is equivalent to @ Resource in the process of Mock, but note that Mock inherits the class that or implements Mock, so the methods from Mock are all null or the return value is null. @ InjectMocks places all the mock objects in the objects of the class that needs to be tested. If you call UserMapper.insert () in the saveTest method above, you need to pile UserMapper.insert () to set the expected return value.
Note when piling: the parameter passed (if any) must be the same object or the same value as the call. If the passed parameter is an object, you need to pile the object and then pile this method. For example, when (userMapper.insert (user)) .thenReturn (rUser) inserts a user object that needs to be piled if the user needs to be checked or other operations before it is inserted (of course the pojp object can be new directly).
If the inserted object is very complex and an empty object is constructed with a constructor, or if the object used by the constructor cannot be constructed directly, but there is no public method to set the value, how to solve this problem? We know that an object's class may have a get method (not necessarily get, but as long as we want to get the parameters in this object, there is a public method to get it), we can use the Mock object, in the body of the method to be tested, if a line calls any of the object's methods (toString (), equals (), get ()) We can all use the same parameters (if you encounter unknown parameters, you can use any (), you can generally know) to set the return value after piling, so that you can execute the later code logic through the parameter verification and other links, while improving the coverage. The pseudo code is as follows.
@ Mock private User user; when (user.get (eq ("userName")) .thenReturn ("testAdmin"); when (user.get (eq ("seq") .thenReturn (4); when (user.get (eq ("password")) .thenReturn ("123456"); when (user.get (eq ("u_id")) .thenReturn ("654321"); Test the code through real test cases
Mockito testing needs to set parameters and expected return values, and all unknown objects encountered in the method body (except the new objects in the method body are not needed) need to be simulated, but in the early days of SpringBoot code completion, compared with the or configuration problem of unit test code in the real scenario, it is a better choice to introduce objects by automatic injection.
ProviderServiceImpl.java-Service class import com.alibaba.dubbo.config.annotation.Service;import com.example.demo.service.DemoService;@Servicepublic class ProviderServiceImpl implements DemoService {@ Override public String sayHello (String name) {return "hello" + name + "!";}} DemoApplicationTests.java-Test class @ RunWith (SpringRunner.class) @ SpringBootTestpublic class DemoApplicationTests {@ Resource DemoService providerService @ Test public void contextLoads () {String result = providerService.sayHello ("Spring Boot Test"); System.out.println ("result is" + result); Assert.assertEquals ("success", "hello Spring Boot Test!", result);}}
It should be noted that DemoApplicationTests needs to be in the same level directory as the startup class main. If it is in the same layer as mvc, there may be some cases where bean cannot be scanned. If the directory level is very deep or the program starts slowly, you can remove SpringBootTest (after removal, you will not start the program, but will only run the test), and run it. The test results are as follows:
Through this annotation way, you can test the dubbo connection (Refernce annotations), you can test the controller layer, redis data, mysql data, will be real simulation, you only need to inject the class you need to test, in the class entry input test parameters, in the testing process, it is best to use debug way, so that you can see each step of the data, but also easy to locate the program's problems (of course, you can also use debug when there are problems).
What is springboot? springboot is a new programming specification, which is designed to simplify the initial construction and development process of new Spring applications. SpringBoot is also a framework that serves the framework, and the scope of services is to simplify configuration files.
After reading the above, have you mastered the solution for SpringBoot unit tests using @ Test without the run method? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.