天天看點

PODAM - Java 對象随機數填充器-屬性随機指派 Mock bean

痛點    

        大家項目中是否遇到過需要編寫測試方法的要求, 編寫代碼過程中,測試代碼的廣覆寫,往往能保證代碼的健壯性。完善的測試用例也能便于後期疊代開發。而編寫測試方法對象的mock資料,如果遇到一個多屬性對象,這項工作又是一個繁重且毫無意義的過程。

于是,下面的代碼,就占用了測試代碼的大部分篇幅:

@Test
    public void testIntegral1(){
//
//        System.out.println(JSONUtil.toJSON(integralService.queryIntegral(1)));
//        IntegralOperateRequest request = IntegralOperateRequest.builder().orderNumber("11").accountId(1).point(100).type(1).build();
//        System.out.println(JSONUtil.toJSON(integralService.reduceOrAddIntegral(request)));
//
//        System.out.println(JSONUtil.toJSON(integralService.queryIntegral(1)));
//
//        System.out.println(JSONUtil.toJSON(integralService.checkIntegralRisk(58865)));
        AppShippingAddress entity = AppShippingAddress.builder().city("深圳市").country("china").firstName("jie").lastName("luo")
                .address1("西麗街道").address2("創智雲城").email("[email protected]").phone("110").province("廣東省").userId(58865)
                .provinceCode("111").site("US").zip("333").build();

        OrderAddressUpdateDTO d= ClazzConverter.converterClass(entity,OrderAddressUpdateDTO.class);
        d.setOrderNumber("62218929766150144");
        System.out.println(appOrderService.updateAddressForBackend(d));



    }
           
@Test
    public void testIntegral() throws Exception {
 //    QueryOrderErpListDTO dto = new QueryOrderErpListDTO();
     //   dto.setPageSize(1);
//        dto.setOrderNumber("1");
//        dto.setSite("US");
//        dto.setPageSize(2);
//        dto.setEmail("77444");
//        dto.setName("jieluo");    

    }
           

而且在新增場景中,我們兩次測試的資料不能重複。這個時候我們又要去重新制造我們的資料。

最近,一個開源項目讓我接觸到了PODAM,可以自動使用随機資料填充Java 對象原始屬性。

使用 PODAM

引入依賴:

<!--PODAM - Java 對象随機數填充器-屬性随機指派 Mock bean-->
            <dependency>
                <groupId>uk.co.jemos.podam</groupId>
                <artifactId>podam</artifactId>
                <version>[latest.version]</version>
            </dependency>
           

實際使用

package govee.app.mall.mapper.mall;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import govee.app.mall.BaseTest;
import govee.app.mall.pojo.constant.BuyTypeEnum;
import govee.app.mall.pojo.constant.SiteCurrencyEnum;
import govee.app.mall.pojo.vo.address.AddressVO;
import org.junit.jupiter.api.Test;
import uk.co.jemos.podam.api.PodamFactory;
import uk.co.jemos.podam.api.PodamFactoryImpl;
import uk.co.jemos.podam.api.RandomDataProviderStrategyImpl;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.function.Consumer;

/**
 * @author dongxu
 * @create 2022-12-25 下午1:42
 */
public class StudyTest extends BaseTest {

    private static final int RANDOM_STRING_LENGTH = 10;

    private static final PodamFactory PODAM_FACTORY = new PodamFactoryImpl();

    private PodamFactory factory;


    /**
     * 初始化一些類型的自定義資料
     */
    static {
        // 字元串
        PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(String.class,
                (dataProviderStrategy, attributeMetadata, map) -> randomString());
        // Integer
        PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Integer.class, (dataProviderStrategy, attributeMetadata, map) -> {
            // 如果是 status 的字段,傳回 0 或 1
            if ("status".equals(attributeMetadata.getAttributeName())) {
                return RandomUtil.randomEle(BuyTypeEnum.values()).getCode();
            }
            return RandomUtil.randomInt();
        });
        // Boolean
        PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Boolean.class, (dataProviderStrategy, attributeMetadata, map) -> {
            // 如果是 deleted 的字段,傳回非删除
            if ("deleted".equals(attributeMetadata.getAttributeName())) {
                return false;
            }
            return RandomUtil.randomBoolean();
        });
    }

    @PostConstruct
    public void init() {
        factory = new PodamFactoryImpl(new RandomDataProviderStrategyImpl());
    }

    public static String randomString() {
        return RandomUtil.randomString(RANDOM_STRING_LENGTH);
    }

    /**
     * 單獨處理個别字段
     *
     * @param clazz     目标類
     * @param consumers 處理個别字段邏輯
     * @param <T>       目标類類型
     * @return 填充後的目标類執行個體
     */
    @SafeVarargs
    public static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
        T pojo = PODAM_FACTORY.manufacturePojo(clazz);
        // 非空時,回調邏輯。通過它,可以實作 Pojo 的進一步處理
        if (ArrayUtil.isNotEmpty(consumers)) {
            Arrays.stream(consumers).forEach(consumer -> consumer.accept(pojo));
        }
        return pojo;
    }

    @Test
    public void testRandomPojo() {

        // 原始用法
        AddressVO addressVO = PODAM_FACTORY.manufacturePojo(AddressVO.class);
        System.out.println(addressVO.toString());

        // 自定義屬性用法
        AddressVO addressVO1 = StudyTest.randomPojo(AddressVO.class, a -> {
            a.setCountry(RandomUtil.randomEle(SiteCurrencyEnum.values()).getSite());
        });
        System.out.println(addressVO1.toString());

        // @PostConstruct 用法
        AddressVO addressVO2 = factory.manufacturePojo(AddressVO.class);
        System.out.println(addressVO2.toString());
        
    }

}
           

Debug  1

PODAM - Java 對象随機數填充器-屬性随機指派 Mock bean

Debug 2

PODAM - Java 對象随機數填充器-屬性随機指派 Mock bean

Debug 3

PODAM - Java 對象随機數填充器-屬性随機指派 Mock bean

最後挂一下github位址:PODAM