Spring Boot 單元測試筆記

1. 導入JUnit5測試框架

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.8.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-launcher</artifactId>
    <version>1.8.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>5.7.2</version>
    <scope>test</scope>
</dependency>

其他按 Spring Boot 項目標準,按需引入即可

2. 編寫Service

/**
 * 假設一個訂單類
 */
public class DemoOrder {
    private String orderId;
    private String orderUser;
    private String contents;
    private Integer quantity;
    private BigDecimal price;
    private BigDecimal total;

    // getter,setter略
}

Mapper 接口

@Mapper
public interface DemoOrderMapper {
    DemoOrder selectOrderByOrderId(String orderId);
    List<DemoOrder> selectOrderByOrderParam(OrderParam param);
}

Service

/**
 * DemoService
 * 此處的兩個方法,一個是傳入String,一個是傳入封裝好的參數類 OrderParam。這兩種方法的測試方法不同
 */
public interface DemoService {
    DemoOrder findOrderByOrderId(String orderId);
    DemoOrder findOrderByRequestParam(OrderParam param);
}
@Service
public class DemoServiceImpl implements DemoService {
    @Autowired
    DemoMapper demoMapper;

    @Override
    public DemoOrder findOrderByOrderId(String orderId) {
        DemoOrder order = demoMapper.selectOrderByOrderId(orderId);
        return order;
    }

    @Override
    public DemoOrder findOrderByRequestParam(OrderParam param) {
        List<DemoOrder> orderList = demoMapper.selectOrderByRequestParam(param);
        return CollectionUtils.isEmpty(orderList) ? null : orderList.get(0);
    }
}

3. 編寫測試類

@DisplayName("單元測試用例")
public class DemoServiceTest {
    @InjectMocks
    DemoServiceImpl demoService; // 此處注意要使用Service接口的實現類

    @Mock
    DemoMapper demoMapper; // 對Mapper使用Mock

    @BeforeEach
    public void setUp() {
        openMocks(this);
        // 老版本是 initMocks(this);
        // 準備數據
        DemoOrder order1 = new DemoOrder();
        order1.setOrderId("001");
        order1.setOrderUser("User1");
        order1.setContents("contents1");
        order1.setQuantity(1);
        order1.setPrice(new BigDecimal("10.5"));
        order1.setTotal(new BigDecimal("10.5"));

        DemoOrder order2 = new DemoOrder();
        order2.setOrderId("002");
        // ... 其他屬性略

        DemoOrder order3 = new DemoOrder();
        order3.setOrderId("003");
        // ... 其他屬性略

        // 以下爲mock mapper的方法模擬
        // 1. 傳String的方法,直接傳入模擬的參數即可
        when(demoMapper.selectOrderByOrderId("001")).thenReturn(order1);
        when(demoMapper.selectOrderByOrderId("002")).thenReturn(order2);
        // ...

        // 2. 傳OrderParam的方法,需要將 when...thenReturn語法改爲 doReturn...when... 語法
        doReturn(Collections.singletonList(order1))
            .when(demoMapper).selectOrderByOrderParam(argThat(
                new ArgumentMatcher<OrderParam>() {
                    @Override
                    public boolean match(OrderParam param) {
                        return param.getOrderId().equals("001")
                    }
                }
        ));
        // 此處也可以將 ArgumentMatcher 單獨定義

        doReturn(Collections.singletonList(order2))
            .when(demoMapper).selectOrderByOrderParam(argThat(
                new ArgumentMatcher<OrderParam>() {
                    @Override
                    public boolean match(OrderParam param) {
                        return param.getOrderId().equals("002")
                    }
                }
        ));
    }

    @Test
    public void findOrderByOrderIdTest() {
        String orderId = "001";
        DemoOrder order = demoService.findOrderByOrderId(orderId);

        assertThat(order.getOrderUser()).isEqualTo("User1");
    }

    @Test
    public void findOrderByOrderParamTest() {
        OrderParam param = new OrderParam();
        param.setOrderId("002");
        DemoOrder order = demoService.findOrderByOrderParam(param);

        assertThat(order.getOrderUser()).isEqualTo("User2"); 
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章