单元测试

时间:2024-03-14 10:06:18
package com.summer.toolkit.service;

import com.summer.toolkit.dto.UserDto;
import com.summer.toolkit.exception.BizException;
import com.summer.toolkit.mock.UserManager;
import com.summer.toolkit.mock.UserServiceImpl;
import com.summer.toolkit.util.FileUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;


@ExtendWith(MockitoExtension.class)
@EnabledIfEnvironmentVariable(named = "DEBUG", matches = "true")
public class UserServiceTest {

    @Mock
    private Logger log;
    @Mock
    private UserManager userManager;

    @InjectMocks
    private UserServiceImpl userService;

    @Test
    public void testCreateUser() {
        // 模拟依赖方法
        Mockito.when(userManager.createUser(any())).thenReturn(Long.valueOf(1));

        // 调用被测方法
        UserDto userDto = this.buildUserDto();
        Long result = userService.createUser(userDto);

        // 验证方法结果
        Long expect = 1L;
        Assertions.assertEquals(expect, result);
        // 验证方法是否被调用
        Mockito.verify(userManager).createUser(userDto);

        // 验证依赖对象只有这一个
        Mockito.verifyNoMoreInteractions(userManager);
    }

    @Test
    public void testUpdateUser() {
        // 模拟依赖方法
        Mockito.when(userManager.updateUser(any())).thenReturn(Boolean.TRUE);
        Mockito.when(userManager.getUser(any())).thenReturn(new UserDto());

        // 调用被测方法
        UserDto userDto = this.buildUserDto();
        userDto.setId(1L);
        Boolean result = userService.updateUser(userDto);

        // 验证方法结果
        Assertions.assertEquals(Boolean.TRUE, result);
        // 验证方法是否被调用
        Mockito.verify(userManager).getUser(any());
        Mockito.verify(userManager).updateUser(any());
    }

    @Test
    public void testGetUser() {
        // 模拟依赖方法
        Mockito.when(userManager.getUser(any())).thenReturn(new UserDto());

        // 调用被测方法
        UserDto userDto = this.buildUserDto();
        userDto.setId(1L);
        UserDto result = userService.getUser(userDto);

        // 验证方法结果
        Assertions.assertNotNull(result);
        // 验证方法是否被调用
        Mockito.verify(userManager).getUser(userDto);
    }

    @Test
    public void testBatchCreateUser() {
        // 模拟依赖方法,指定单个异常类型
        Mockito.when(userManager.createUser(any())).thenThrow(BizException.class);

        // 调用被测方法
        List<UserDto> param = new ArrayList<>();
        UserDto userDto = this.buildUserDto();
        param.add(userDto);
        Boolean result = userService.batchCreateUser(param);

        // 验证方法结果
        Assertions.assertEquals(Boolean.FALSE, result);
        // 验证方法是否被调用,默认一次
        Mockito.verify(userManager).createUser(userDto);
        // 验证方法是否被调用了1次
        Mockito.verify(userManager, Mockito.times(1)).createUser(any());
    }

    @Test
    public void testBatchCreateUserTimes() {
        // 模拟依赖方法,指定单个异常类型
        Mockito.when(userManager.createUser(any())).thenReturn(1L);

        // 调用被测方法
        List<UserDto> param = new ArrayList<>();
        UserDto userDto = this.buildUserDto();
        param.add(userDto);
        param.add(userDto);
        param.add(userDto);
        Boolean result = userService.batchCreateUser(param);

        // 验证方法结果
        Assertions.assertEquals(Boolean.TRUE, result);
        // 验证方法是否被调用了3次
        Mockito.verify(userManager, Mockito.times(3)).createUser(any());
    }

    @Test
    public void testFileUtils() {
        // 构建对象
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");

        // 模拟对应的类
        // JDK11及以上版本中,try块中的变量可以在外部声明
        MockedStatic<FileUtils> mocked = Mockito.mockStatic(FileUtils.class);
        try (mocked) {
            // 模拟依赖静态方法
            mocked.when(() -> FileUtils.readFileAllLines(anyString())).thenReturn(list);

            // 调用被测方法
            List<String> lines = FileUtils.readFileAllLines(anyString());

            // 验证方法结果
            Assertions.assertEquals(list.size(), lines.size());
        } catch (Exception e) {
            log.error("模拟静态方法异常:{}", e.getMessage(), e);
        }
    }

    /**
     * 构建用户数据传输对象
     *
     * @return UserDto 返回构建好的用户数据传输对象
     */
    private UserDto buildUserDto() {
        UserDto userDto = new UserDto();
        userDto.setUsername("小明");
        userDto.setBirthday(new Date());
        userDto.setAddress("北京市大兴区亦庄经济开发区");
        userDto.setComment("加麻加辣");
        userDto.setGender(1);
        return userDto;
    }

}