Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Calling Non Public Setters

DZone's Guide to

Calling Non Public Setters

· Agile Zone ·
Free Resource

Discover how you can take agile development to the next level with low-code.

Properties with non public setters sometimes make sense – until a unit test requires an object to be set up in a specific state. I don’t want to make the setter public just because of the tests, so I wrote a small helper function that can call non public setters.

The helper returns the object itself, to allow a fluent syntax inside member initialization expressions and uses a lambda to select the member (I do like compile time checking whenever it’s possible).

This is actual code I wrote last week using the helper. It’s part of a set up of an object collection used for unit tests.

Orders = new List<Order>
{
  new Order
  {
    OrderId = 983427,
  }.CallNonPublicSetter(o => o.StatusId, OrderStatus.Confirmed),
  new Order
  {
    OrderId = 18956,
  }.CallNonPublicSetter(o => o.StatusId, OrderStatus.Delivered)
};

The helper is implemented using reflection to access the property to bypass the protection level of the setter.

static class NonPublicSetter
{
  public static TObject CallNonPublicSetter<TObject, TProperty>(this TObject obj,
    Expression<Func<TObject, TProperty>> property, TProperty value)
  {
    var memberExp = (MemberExpression)property.Body;
 
    ((PropertyInfo)memberExp.Member).SetValue(obj, value);
 
    return obj;
  }
}

Using reflection to bypass a class’ protection and access protected or private members is not recommended in production code – but for unit tests I think it makes perfect sense. In the sample above from last week, it’s of course possible to create an object and bring it through a number of operations to put it in the required state. That’s what happens in the production code. But for a unit test it’s just awkward to have to push an object through three or four state transitions just to get it set up for a test of a later state transition. It’s much better to just set up the object to be in a known state and then call the method being tested.

Download this eBook to learn how to prepare your business for agile adoption, how to ensure the proper business-IT collaboration that is critical for agile development, and how to choose the right stakeholders to increase productivity and enable accelerated time-to-value.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}