cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

UnitTest with dynamic attribute

Former Member
0 Likes
1,243

Hi. I'm writing an unit test. I need to populate AbstractOrderModel discountValue with a double. But it turned out, that discountValue is dynamic attribute, so my test doesn't work.

Maybe you have any idea how to solve this?

 @Accessor(qualifier = "discountValues", type = Accessor.Type.SETTER)
     public void setDiscountValues(final List<DiscountValue> value)
     {
         getPersistenceContext().setDynamicValue(this,DISCOUNTVALUES, value);
     }

should I use Integration test? Or maybe import file with spring config into my unit test?

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Likes

we use the following snippet to create unit-testable model instances

 class AbstractModelBuilder<T extends ItemModel> {


 protected Map<String, DynamicAttributeHandler> handlers = new HashMap<>();
 protected Class<T> clazz;

 // lots of withXXX methods
 
 public T buildInstance() {
         try{
             Map<String, Object> attributeValues = new HashMap<>();
             ItemContextBuilder mockContextBuilder = ItemContextBuilder.createMockContextBuilder(clazz, getRandomPK(),new Locale("de"), attributeValues);
             if (handlers.size() > 0) {
                 mockContextBuilder.setDynamicAttributesProvider(new DefaultDynamicAttributesProvider(handlers));
             }
             ItemModelInternalContext ctx = mockContextBuilder.build();
             T instance = clazz.getConstructor(ItemModelContext.class).newInstance(ctx);
             updateInstanceWithSpecifiedProperties(instance);
             return instance;
         } catch (Exception e) {
             throw new RuntimeException("Cannot create instance of type " + ClassUtils.getShortClassName(clazz), e);
         }
     }

 protected void addHandler(String property, DynamicAttributeHandler handler) {
     handlers.put(property, handler);
 }

 protected void updateInstanceWithSpecifiedProperties(T instance) {
     // some reflection magic to set values into the model
 }
 }


where handlers is filled like this (in this example for the "europe1Prices" property for Product)

 addHandler("europe1Prices", new DynamicAttributeHandler<Collection<PriceRowModel>, ProductModel>() {
         Collection<PriceRowModel> priceRowModels;

         @Override
         public Collection<PriceRowModel> get(ProductModel productModel) {
             return priceRowModels;
         }

         @Override
         public void set(ProductModel productModel, Collection<PriceRowModel> priceRowModels) {
             this.priceRowModels = priceRowModels;
         }
     });


this enables us to use the real model in unittests, which is much more convenient than using mocks. localized attributes work as well

Answers (1)

Answers (1)

Former Member
0 Likes

Hi,

you should use Mockito. Examples can be found in AbstractOrderPopulatorTest for instance.

 final DiscountValue discountValue = mock(DiscountValue.class);
 given(abstractOrderEntryModel.getDiscountValues()).willReturn(Collections.singletonList(discountValue));
 given(Double.valueOf(discountValue.getAppliedValue())).willReturn(Double.valueOf(2.3));