当前位置:网站首页>Unit testing classic three questions: what, why, and how?
Unit testing classic three questions: what, why, and how?
2022-07-02 04:17:00 【Mingmingruyue senior】
One 、 background
Writing qualified unit tests can be said to be Java The basic skills of programmers .
But many companies have requirements for single test coverage , It's usually required in 60% To 90% Unequal .
But many students are more or less resistant to unit testing , On how to write “ standard ” There is a problem with your unit test code .
Some students write unit tests , Just dealing with work , It can't play the role that a single test should play .
This article answers three basic questions about unit testing , That is, what unit testing is , Why write unit tests , How to write unit tests ?
Two 、 Classic three questions
2.1 What is unit testing ?
The English word for unit test is : Unit Test .
What is? Unit ( unit )?
A unit can be a method 、 It can be a class , It can also be a package or even a subsystem .
The unit tests we write during development , It is usually to test some or all of the methods in a class , To verify the correctness of their functions .
Usually used to validate a given specific input , Whether it can give the expected output .
2.2 Why write unit tests ?
We know that the sooner we find a mistake , The sooner you solve , The better .
Writing unit tests can verify the correctness of the code at the coding stage , Correct as soon as possible .
Unit testing can usually help us find some low-level errors as soon as possible 、 Some logical errors , Very valuable .
If writing unit tests is more comprehensive , Then it's easier to refactor the code , If the unit test fails after refactoring, there is a problem with the code .
But in the domestic environment , The construction period is tight , And writing unit tests is time-consuming , There is often a mentality of coping with the test .
If it is because writing a single test is a waste of time , You can refer to another article of mine to automatically generate some single test code , You only need to make a few adjustments :
《 Say goodbye to overtime / Emancipate your hands and improve the coverage of single test Java Automatically generate single test code artifact recommendation 》
Some students don't recognize the value of unit testing , I think the functional test phase can verify the correctness of the code , Writing unit tests is pure dogmatism , A waste of time .
Unit testing is an important means to ensure code quality .
(1) Although no single test will be written, the function test will also be carried out , However, many problems found in the test phase may be found and solved in the unit test phase .
(2) Sometimes when new functions are developed and the amount of data is small , The functional test scenario does not cover , It may bring errors that could have been found during unit testing to the line .
2.3 How to write unit tests ?
2.3.1 Introduce
Here we only talk about the big logic of unit testing , Let novices know exactly what to write in a single test , Not at all JUnit Getting started with .
The trilogy of unit testing : given -> when -> then
So-called given That is, construction parameters and conditions ( Such as mock Rely on the bean ), So-called when Execution target method ; So-called then That is, under given parameters and conditions , After implementing the target method , What are our expectations .
Here is the sample code :
@Test
public void shouldDeliverCargoToDestination() {
// given
Driver driver = new Driver("Teddy");
Cargo cargo = new Cargo();
Position destinationPosition = new Position("52.229676", "21.012228");
Truck truck = new Truck();
truck.setDriver(driver);
truck.load(cargo);
truck.setDestination(destinationPosition);
// when
truck.driveToDestination();
// then
assertEquals(destinationPosition, truck.getCurrentPosition());
}
Sample code source :https://blog.j-labs.pl/2017/02/Given-When-Then-pattern-in-unit-tests
In a word : Unit tests are similar to those in experiments 【 Control variable method 】, Construct known parameters ,mock Dependent interfaces , Assert whether the result of the operation meets the expectation .
principle :
(1) Test should cover normal use cases as much as possible , Also override exception use cases .
(2) Try to ensure that each branch condition covers .
2.3.2 Case study
Case a
String splicing tool class
import java.util.Iterator;
import java.util.List;
public class SomeUtils {
/** * Concatenate strings with English commas */
public static String joinWithDot(List<String> params){
StringBuilder stringBuilder = new StringBuilder();
Iterator<String> iterator = params.iterator();
while (iterator.hasNext()) {
stringBuilder.append(iterator.next()).append(".");
}
return stringBuilder.toString();
}
}
It is recommended to use... When splicing strings with actual encoding StringJoiner class
We use 《 Say goodbye to overtime / Emancipate your hands and improve the coverage of single test Java Automatically generate single test code artifact recommendation 》 To introduce the Squaretest The plug-in automatically generates a single test :
import org.junit.Test;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
public class SomeUtilsTest {
@Test
public void testJoinWithDot() {
assertEquals("result", SomeUtils.joinWithDot(Arrays.asList("value")));
}
}
We modify it on this basis :
public class SomeUtilsTest {
@Test
public void testJoinWithDot() {
assertEquals(null, SomeUtils.joinWithDot(null));
assertEquals("a.b", SomeUtils.joinWithDot(Arrays.asList("a","b")));
assertEquals("a.null.c", SomeUtils.joinWithDot(Arrays.asList("a",null,"c")));
}
}
although , It seems that there are only assertions , such as :
assertEquals(null, SomeUtils.joinWithDot(null));
Here is actually a kind of abbreviation , In fact, it still conforms to Given when then The pattern of :
@Test
public void testJoinWithDot() {
// given
List<String> params = null;
// when
String result = SomeUtils.joinWithDot(null);
// then
assertEquals(null, result);
}
Run unit tests , Null pointer found :
It shows that our code is not robust enough , Need modification :
/** * Concatenate strings with English commas */
public static String joinWithDot(List<String> params){
if(CollectionUtils.isEmpty(params)){
return null;
}
StringBuilder stringBuilder = new StringBuilder();
Iterator<String> iterator = params.iterator();
while (iterator.hasNext()) {
stringBuilder.append(iterator.next()).append(".");
}
return stringBuilder.toString();
}
Run again , Wrong again. :
We assert that assertEquals("a.b", SomeUtils.joinWithDot(Arrays.asList("a","b")));
The result after execution should be “a.b” But the actual implementation result is “a.b.”
We continue to revise :
/** * Concatenate strings with English commas */
public static String joinWithDot(List<String> params){
if(CollectionUtils.isEmpty(params)){
return null;
}
StringBuilder stringBuilder = new StringBuilder();
Iterator<String> iterator = params.iterator();
while (iterator.hasNext()) {
String each = iterator.next();
stringBuilder.append(each);
if (iterator.hasNext()) {
stringBuilder.append(".");
}
}
return stringBuilder.toString();
}
Pass the unit test , Explain that it meets expectations .
For the testing of this similar tool class , You can refer to commons-lang、commons-collections4 And other open source projects .
https://github.com/apache/commons-lang
https://github.com/apache/commons-collections
Case 2
In normal development, it is more common to Spring Of Bean To test , It's like this :
@Service
public class UserManager {
@Setter
private UserDAO userDAO;
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public List<UserDO> someThing(Param param) {
List<UserDO> result = new ArrayList<>();
if(param == null) {
return result;
}
List<String> userIds = param.getUserIds();
if(CollectionUtils.isEmpty(userIds)) {
return result;
}
List<UserDO> users = userDAO.findByIds(userIds);
if(CollectionUtils.isEmpty(users)) {
return result;
}
return users.stream().filter(UserDO::getCanShow).collect(Collectors.toList());
}
}
notes : Usually dependent Bean Method time ,
Continue to use the plug-in to generate unit test code with one click :
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class UserManagerTest {
@Mock
private UserDAO mockUserDAO;
@InjectMocks
private UserManager userManagerUnderTest;
@Test
public void testSomeThing() {
// Setup
final Param param = new Param();
param.setUserIds(Arrays.asList("value"));
param.setOthers("others");
// Configure UserDAO.findByIds(...).
final UserDO userDO = new UserDO();
userDO.setCanShow(false);
userDO.setName("name");
final List<UserDO> userDOS = Arrays.asList(userDO);
when(mockUserDAO.findByIds(Arrays.asList("value"))).thenReturn(userDOS);
// Run the test
final List<UserDO> result = userManagerUnderTest.someThing(param);
// Verify the results
}
@Test
public void testSomeThing_UserDAOReturnsNoItems() {
// Setup
final Param param = new Param();
param.setUserIds(Arrays.asList("value"));
param.setOthers("others");
when(mockUserDAO.findByIds(Arrays.asList("value"))).thenReturn(Collections.emptyList());
// Run the test
final List<UserDO> result = userManagerUnderTest.someThing(param);
// Verify the results
assertEquals(Collections.emptyList(), result);
}
}
We follow the business logic , Simply modify the generated single test code :
@Test
public void testSomeThing() {
// given
final Param param = new Param();
List<String> userIds = Arrays.asList("value");
param.setUserIds(userIds);
param.setOthers("others");
final UserDO userCanNotShow = new UserDO();
userCanNotShow.setCanShow(false);
userCanNotShow.setName("name");
final UserDO userCanShow = new UserDO();
userCanShow.setCanShow(true);
userCanShow.setName("name");
final List<UserDO> userDOS = Arrays.asList(userCanNotShow, userCanShow);
when(mockUserDAO.findByIds(userIds)).thenReturn(userDOS);
// when
final List<UserDO> result = userManagerUnderTest.someThing(param);
// then
assertEquals(1, result.size());
assertSame(userCanShow, result.get(0));
}
You only need to write part of the code to complete the unit test , It can save us a lot of time .
if necessary mock Private method 、 Static methods, etc. please learn by yourself , have access to powmock Tools such as .
We can also use other tools , Automatically generate test parameters or return values .
https://github.com/j-easy/easy-random
You can refer to my previous article :
《Java Efficient artifact for constructing objects :easy-random brief introduction 》
One or two lines can construct a very complex object or object list .
《Java The artifact of generating test strings from unit tests :java-faker》
If we want to randomly construct people's names 、 Place names 、 The weather 、 School 、 Color 、 occupation , Even a string that matches a regular expression
3、 ... and 、 summary
This article briefly introduces what unit testing is 、 Why and how to write unit tests .
Hopefully that helped , If you have any questions, please leave a message and communicate with me .
It's not easy to create , If this article helps you , Welcome to thumb up 、 Collection and attention , Your support and encouragement , It's the biggest driving force of my creation .
边栏推荐
- The original author is out! Faker. JS has been controlled by the community..
- Go language introduction
- Li Kou interview question 02.08 Loop detection
- 60后关机程序
- C language guessing numbers game
- Introduction to vmware workstation and vSphere
- Websites that it people often visit
- Handling of inconsistency between cursor and hinttext position in shutter textfield
- Fluent icon demo
- Is it safe to open an account with first venture securities? I like to open an account. How can I open it?
猜你喜欢
Typescript practice for SAP ui5
Delete the code you wrote? Sentenced to 10 months!
A summary of common interview questions in 2022, including 25 technology stacks, has helped me successfully get an offer from Tencent
FAQ | FAQ for building applications for large screen devices
Actual combat | use composite material 3 in application
Li Kou interview question 02.08 Loop detection
Dare to go out for an interview without learning some distributed technology?
JVM knowledge points
《动手学深度学习》(二)-- 多层感知机
WPViewPDF Delphi 和 .NET 的 PDF 查看组件
随机推荐
uni-app - 实现获取手机验证码倒计时 60 秒(手机号+验证码登录功能)
【c语言】动态规划---入门到起立
Delete the code you wrote? Sentenced to 10 months!
Use of go package
Pytoch yolov5 runs bug solution from 0:
First acquaintance with string+ simple usage (II)
Is the product of cancer prevention medical insurance safe?
A thorough understanding of the development of scorecards - the determination of Y (Vintage analysis, rolling rate analysis, etc.)
XSS prevention
Exposure X8标准版图片后期滤镜PS、LR等软件的插件
【leetcode】81. Search rotation sort array II
Sorted out an ECS summer money saving secret, this time @ old users come and take it away
Go branch and loop
Sword finger offer II 006 Sort the sum of two numbers in the array
Fluent icon demo
手撕——排序
2022-07-01: at the annual meeting of a company, everyone is going to play a game of giving bonuses. There are a total of N employees. Each employee has construction points and trouble points. They nee
[live broadcast review] the first 8 live broadcasts of battle code Pioneer have come to a perfect end. Please look forward to the next one!
Pytorch-Yolov5從0運行Bug解决:
Microsoft Research Institute's new book "Fundamentals of data science", 479 Pages pdf