Domain Model (Exposing Public Properties)

2019-09-05 05:47发布

问题:

So when building my domain model i am trying to be pragmatic about exposing only whats necessary for driving the behavior but my unit tests are requiring me to expose public getters that are only really needed from within the class. how is everyone handling this? my domain layer is only being accessed through my application services layer, so is it really that big of a deal? should i make them internal and give the test project access?

any help would be great!

回答1:

I agree with Eric's statement that unit tests should not affect class APIs.

In your situation, it sounds like your design may not be quite correct. You're talking about unit tests that need to check private variables - but a unit test should be fully defined using public APIs.

Either split up your objects so that the private fields are exposed at some layer (making the objects more fine-grained), or change your tests to not need access to those private fields (making your unit tests more coarse-grained).

One useful tool is Code Contracts. You can define very fine-grained tests (post-conditions and object invariants, defined in terms of private fields) using Code Contracts, and make your unit testing a little more coarse-grained. Some of my unit tests do nothing more than invoke a method and ensure the Code Contracts don't fire.



回答2:

I think it is always a bad idea to change the public interface of a class to accommodate a unit test. That is the "tail wagging the dog".

If you must access internal state of an object to test it, I would create some extension methods in my testing namespace that allow easy access to an object's private properties (e.g., T GetPropertyValueByName(this string propertyName).



回答3:

Without seeing your code it seems that your design might need to be changed to make it more testable. Think about extracting an interface and implimenting dependancy injection to your class so you can set internal state if you need to. Using this method, you can set private members during construction. Also try using a mocking library. Moq is my favorite.



回答4:

You can make the unit test library a friend of the domain library and change the private members of your domain classes to internal.