单元测试场景示例和部分Java代码实现(全)

26 篇文章 0 订阅
12 篇文章 0 订阅

了解单元测试参考文章高质量单元测试要求和依据阿里巴巴编码规范的Java单元测试示例-CSDN博客

java 写单元测试的常用技术组件和mock示例-CSDN博客

单元测试场景示例:

1.方法输入输出验证

测试一个计算类的方法,如加法、减法、乘法和除法运算是否正确。

2.边界条件测试

测试一个函数在处理边界数据时的行为,例如列表为空或只有一个元素时的情况,或者数学函数中除数为零等非法情况。

3.错误/异常处理测试

确保当程序遇到预期错误(如文件未找到、网络连接失败、无效用户输入)时,会抛出适当的异常,并且后续逻辑能够正常执行。

4.集成测试中的部分隔离

使用mock对象来模拟依赖的服务或组件,确保即使这些依赖不可用或有未知行为,被测试代码也能按预期工作。

5.多线程和并发测试

使用@Test注解的org.junit.jupiter.api.RepeatedTest结合并发工具,测试多线程环境下的类或方法的线程安全性和正确性。

6.数据库操作测试

对于涉及数据库操作的方法,可以使用像H2这样的内存数据库,配合Spring的@DataJpaTest或Hibernate的测试工具进行单元测试。

每个测试都应该独立运行且结果可预测,通过设定明确的前置条件、执行动作并验证结果,确保单个模块的功能完整性。

Java编写单元测试的常用技术实现如下,供探讨学习:

1.JUnit 5

JUnit 是Java中最广泛使用的单元测试框架,最新版本是JUnit 5,它提供了丰富的注解、条件测试、参数化测试、异常测试等功能。

   import org.junit.jupiter.api.Test;
   import static org.junit.jupiter.api.Assertions.assertEquals;

   public class CalculatorTest {
       @Test
       void testAddition() {
           Calculator calculator = new Calculator();
           int result = calculator.add(2, 3);
           assertEquals(5, result, "2 + 3 should equal 5");
       }

       @Test
       void testDivisionByZero() {
           Calculator calculator = new Calculator();
           assertThrows(ArithmeticException.class, () -> calculator.divide(1, 0));
       }
   }

2.Mocking Frameworks

Mockito 和 EasyMock 可用于模拟对象行为以隔离被测试代码与其他依赖项的交互。

   import org.junit.jupiter.api.Test;
   import static org.mockito.Mockito.*;

   class UserServiceTest {
       @Test
       void testUserRegistration() {
           UserRepository repo = mock(UserRepository.class);
           when(repo.save(any(User.class))).thenReturn(true);

           UserService userService = new UserService(repo);
           User newUser = new User("testUser", "password");

           boolean registrationSuccess = userService.register(newUser);

           verify(repo).save(newUser);
           assertTrue(registrationSuccess);
       }
   }

3.Assertion Libraries

Hamcrest 或 AssertJ 提供了更丰富和可读性更强的断言表达式。

   import static org.assertj.core.api.Assertions.assertThat;

   @Test
   void testArraySorting() {
       Integer[] numbers = {3, 1, 4, 1, 5, 9};
       Arrays.sort(numbers);
       assertThat(numbers).containsExactly(1, 1, 3, 4, 5, 9);
   }

Spring boot maven工程常会结合Spring Boot Test和JUnit5框架,单元测试代码示例实现:

1. 测试无依赖的简单服务类

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class SimpleServiceTest {

    private final SimpleService simpleService = new SimpleService();

    @Test
    void testSimpleFunction() {
        String result = simpleService.concatenate("Hello", "World");
        assertEquals("HelloWorld", result);
    }
}

2. 使用@SpringBootTest注解进行集成测试(包括自动注入)

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@SpringBootTest
class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    void testUserCreation() {
        User user = userService.createUser("testuser", "password");
        assertNotNull(user.getId(), "User ID should not be null after creation");
    }
}

3. 使用Mockito模拟依赖项进行单元测试

import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class OrderServiceTest {

    @Mock
    private ProductService productService;

    @InjectMocks
    private OrderService orderService;

    @BeforeEach // JUnit5中的初始化方法
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    void testOrderTotalWithMockedProduct() {
        Product product = new Product(1L, "Item", 10.0);
        Mockito.when(productService.getProductById(1L)).thenReturn(product);

        double total = orderService.calculateOrderTotal(1L, 2);
        assertEquals(20.0, total, 0.001, "Order total calculation is incorrect");

        Mockito.verify(productService).getProductById(1L);
    }
}

4. 数据库操作的单元测试(使用Spring Data JPA与内嵌数据库如H2)

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // 使用内嵌H2数据库
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    void whenFindByUsername_thenReturnUser() {
        // 假设已有用户数据
        userRepository.save(new User("testuser", "password"));

        Optional<User> foundUser = userRepository.findByUsername("testuser");
        assertThat(foundUser).isPresent();
        assertThat(foundUser.get().getUsername()).isEqualTo("testuser");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值