2011-08-15 27 views
29

Có thư viện java nào có thể giúp tạo các phiên bản của các lớp để kiểm tra không? Một trong đó kiểm tra các thuộc tính của một bean và điền nó với dữ liệu ngẫu nhiên.
Tôi về cơ bản tìm kiếm Java tương đương với Object Hydrator cho C#.Tự động điền các thuộc tính nguyên thủy với dữ liệu ngẫu nhiên?

+0

Bạn cũng có thể có một cái nhìn tại https://github.com/nomemory/mockneat. Đó là thư viện có thể được sử dụng chính xác cho việc này - để điền vào các đối tượng có dữ liệu (hợp lệ). –

Trả lời

37

Bạn có thể sử dụng PoDaM:

PodamFactory factory = new PodamFactoryImpl(); 
Pojo myPojo = factory.manufacturePojo(Pojo.class); 
+0

Nó cũng ở Maven Central, hay. – prasopes

+0

Tôi có thể sử dụng thư viện này để tạo các tham số ngẫu nhiên cho cuộc gọi phương thức không? –

+0

@Alex, chỉ cần điền POJO sau đó đọc các trường của nó – msangel

13

Tôi không biết về một khung công tác, nhưng thật dễ dàng để viết một trong những khung đó. Sự phức tạp xuất hiện trong các thuộc tính không đơn giản, còn gọi là các liên kết đối tượng. Một cái gì đó như thế này xử lý các vấn đề cơ bản và sau đó một số:

public static void randomlyPopulateFields(Object object) { 
    new RandomValueFieldPopulator().populate(object); 
} 

public static class RandomValueFieldPopulator { 
    public void populate(Object object) { 
     ReflectionUtils.doWithFields(object.getClass(), new RandomValueFieldSetterCallback(object)); 
    } 

    private static class RandomValueFieldSetterCallback implements FieldCallback { 
     private Object targetObject; 

     public RandomValueFieldSetterCallback(Object targetObject) { 
      this.targetObject = targetObject; 
     } 

     @Override 
     public void doWith(Field field) throws IllegalAccessException { 
      Class<?> fieldType = field.getType(); 
      if (!Modifier.isFinal(field.getModifiers())) { 
       Object value = generateRandomValue(fieldType, new WarnOnCantGenerateValueHandler(field)); 
       if (!value.equals(UNGENERATED_VALUE_MARKER)) { 
        ReflectionUtils.makeAccessible(field); 
        field.set(targetObject, value); 
       } 
      } 
     } 
    } 
} 

public static Object generateRandomValue(Class<?> fieldType, CantGenerateValueHandler cantGenerateValueHandler) { 
    if (fieldType.equals(String.class)) { 
     return UUID.randomUUID().toString(); 
    } else if (Date.class.isAssignableFrom(fieldType)) { 
     return new Date(System.currentTimeMillis() - random.nextInt(DATE_WINDOW_MILLIS)); 
    } else if (Number.class.isAssignableFrom(fieldType)) { 
     return random.nextInt(Byte.MAX_VALUE) + 1; 
    } else if (fieldType.equals(Integer.TYPE)) { 
     return random.nextInt(); 
    } else if (fieldType.equals(Long.TYPE)) { 
     return random.nextInt(); 
    } else if (Enum.class.isAssignableFrom(fieldType)) { 
     Object[] enumValues = fieldType.getEnumConstants(); 
     return enumValues[random.nextInt(enumValues.length)]; 
    } else { 
     return cantGenerateValueHandler.handle(); 
    } 
} 
+0

Giá trị hoàn toàn ngẫu nhiên cho các kiểu nguyên thủy là tầm thường. Các mối quan tâm thực tế hơn rất nhiều xung quanh các trường nullable và nullable, các giá trị min/max, phạm vi ngày và các mẫu chuỗi. –

+0

@Alistair: Đồng ý. Tôi đã viết một trình tạo biểu đồ đối tượng ngẫu nhiên có khả năng phức tạp hoặc khá phức tạp trước đó, và kinh nghiệm đã dẫn tôi đến kết luận rằng đó là một mẫu thử nghiệm và nên tránh nếu có thể. –

+0

@RyanStewart tại sao nó nên tránh? (Tôi hiện đang ngồi xung quanh tránh viết mã sẽ tạo ra một số đối tượng miền, tất cả được điền đầy đủ dữ liệu ngẫu nhiên, để kiểm tra các lớp dịch vụ và contoller của tôi) – NimChimpsky

1

Để thử nghiệm, nhóm của chúng tôi đã thành công với JUnit và Mockito. Đây là link to a Mockito answer.

Tôi không chắc chắn nếu điền dữ liệu ngẫu nhiên sẽ là một thử nghiệm có ý nghĩa. Có lẽ một thử nghiệm có ý nghĩa hơn sẽ kiểm tra các điều kiện bình thường, ranh giới và lỗi.

+3

Tôi thực sự mong ước một công cụ tương tự nhiều lần (đến mức tôi bắt đầu viết một bản thân). Các điều kiện bình thường/ranh giới/lỗi tốt cho thử nghiệm đơn vị nói chung, tuy nhiên, để kiểm tra hiệu năng/tải và thử nghiệm hộp đen, đôi khi bạn cần khối lượng dữ liệu thử nghiệm đáng kể. –

17

Hãy xem Đậu Ngẫu nhiên:

https://github.com/benas/random-beans

Nó cho phép bạn để cư một đồ thị đối tượng Java với dữ liệu ngẫu nhiên.

Hy vọng nó giúp Trân

+0

Chỉ xảy ra để xem bài đăng này. Chưa thử, nhanh chóng lướt qua, dường như là tốt vì nó hỗ trợ phân cấp/lồng nhau của các đối tượng. Công việc tốt đẹp. Cảm ơn bạn cho cùng. – Rao

0

Tôi đã sử dụng phản xạ và đệ quy vào đây để có được tất cả các lĩnh vực dân cư trong đối tượng mạnh mẽ của tôi rằng tôi muốn đi xét nghiệm. Đây là sử dụng PODAM cũng như tôi hy vọng ai đó sẽ thấy điều này hữu ích.

public class Populate { 

    private final PodamFactory podamFactory = new PodamFactoryImpl(); 

    private <P> P getManufacturedPojo(final Class<P> klass) { 
     return podamFactory.manufacturePojo(klass); 
    } 

    private Object populateAllIn(final Class targetClass) throws IllegalAccessException, InstantiationException { 
     final Object target = targetClass.newInstance(); 

     //Get all fields present on the target class 
     final Set<Field> allFields = getAllFields(targetClass, Predicates.<Field>alwaysTrue()); 

     //Iterate through fields 
     for (final Field field : allFields) { 

      //Set fields to be accessible even when private 
      field.setAccessible(true); 

      final Class<?> fieldType = field.getType(); 
      if (fieldType.isEnum() && EnrichmentType.class.isAssignableFrom(fieldType)) { 
       //handle any enums here if you have any 
      }    

      //Check if the field is a collection 
      if (Collection.class.isAssignableFrom(fieldType)) { 

       //Get the generic type class of the collection 
       final Class<?> genericClass = getGenericClass(field); 

       //Check if the generic type of a list is abstract 
       if (Modifier.isAbstract(genericClass.getModifiers())) { 

        //You might want to use any class that extends 
        //Your abstract class like 

        final List<Object> list = new ArrayList<>(); 
        list.add(populateAllIn(ClassExtendingAbstract.class)); 
        field.set(target, list); 

       } else { 
        final List<Object> list = new ArrayList<>(); 
        list.add(populateAllIn(genericClass)); 
        field.set(target, list); 
       } 

      } else if ((isSimpleType(fieldType) || isSimplePrimitiveWrapperType(fieldType)) && !fieldType.isEnum()) { 
       field.set(target, getManufacturedPojo(fieldType)); 

      } else if (!fieldType.isEnum()) { 
       field.set(target, populateAllIn(fieldType)); 
      } 
     } 
     return target; 
    } 

Và một số phương pháp trợ giúp. Mã có thể không hoàn hảo nhưng hoạt động :).

private Class<?> getGenericClass(final Field field) { 
    final ParameterizedType collectionType = (ParameterizedType) field.getGenericType(); 
    return (Class<?>) collectionType.getActualTypeArguments()[0]; 
} 

private boolean isSimpleType(final Class<?> fieldType) { 
    return fieldType.isPrimitive() 
      || fieldType.isEnum() 
      || String.class.isAssignableFrom(fieldType) 
      || Date.class.isAssignableFrom(fieldType); 
} 

private boolean isSimplePrimitiveWrapperType(final Class<?> fieldType) { 
    return Integer.class.isAssignableFrom(fieldType) 
      || Boolean.class.isAssignableFrom(fieldType) 
      || Character.class.isAssignableFrom(fieldType) 
      || Long.class.isAssignableFrom(fieldType) 
      || Short.class.isAssignableFrom(fieldType) 
      || Double.class.isAssignableFrom(fieldType) 
      || Float.class.isAssignableFrom(fieldType) 
      || Byte.class.isAssignableFrom(fieldType); 
} 

Cảm ơn và nếu có cách dễ dàng hơn để điền mọi thứ, vui lòng cho tôi biết.

5

Bạn có thể thanh toán randomizer để tạo dữ liệu ngẫu nhiên. Thư viện này giúp tạo dữ liệu ngẫu nhiên từ lớp Mô hình đã cho.Kiểm tra bên dưới mã mẫu.

public class Person { 

    @FirstName 
    String mFirstName; 

    @LastName 
    String mLastName; 

    @Number(min = 14,max = 25,decimals = 0) 
    int age; 

    @DateValue(from = "01 Jan 1990",to = "31 Dec 2002" , customFormat = "dd MMM yyyy") 
    String dateOfBirth; 

    @Email 
    String mEmailId; 

    @StreetAddress 
    public String streetAddress; 

    @State 
    public String state; 

    //Person can have minimum 1 Phone number and maximum 3 phone number 
    @Phone(country = Phone.Country.INDIA) 
    @CollectionDescriptor(min = 1,max = 3) 
    List<String> phones; 

} 

//Generate random 100 Person(Model Class) object 
Generator<Person> generator = new Generator<>(Person.class); 
List<Person> persons = generator.generate(100);       

Vì có nhiều trình tạo dữ liệu được tích hợp có thể truy cập bằng chú thích, Bạn cũng có thể tạo trình tạo dữ liệu tùy chỉnh. Tôi khuyên bạn nên xem qua tài liệu được cung cấp trên trang thư viện.

+1

Thư viện này có vẻ tốt ngoại trừ việc nó yêu cầu sửa đổi Đậu chỉ để thử nghiệm. – Divick

5

https://github.com/benas/random-beans đã thực hiện công việc cho tôi, trong khi PoDam thất bại với trình cài đặt "thông thạo" và câu trả lời của Ryan Stewart không hoàn chỉnh để sao chép-dán vì có tham chiếu đến các lớp không được hiển thị! Với ngẫu nhiên đậu nó dễ dàng như:

Auction auction = EnhancedRandom.random(Auction.class); 

Gradle:

testCompile ('io.github.benas:random-beans:3.4.0') 
+0

Kể từ phiên bản 7.0.1 Podam hỗ trợ cài đặt thông thạo theo mặc định và trước đó có thể gọi chúng bằng cách xác định ClassInfoStrategy tùy chỉnh. – divanov

Các vấn đề liên quan