Implementing Objects in Test Classes

I use MS UnitTesting and try to find a way to write my first unit tests. It seems like all my unit tests start with creating the exact same objects ...

[TestMethod] CanCreateOrder() { <create an order> ... } [TestMethod] CanSetOrderDeliveryAddress() { <create an order> <create an address> order.DeliveryAddress = address; ... } [TestMethod] CanDispatchAnOrder() { <create an order> <create an address> order.DeliveryAddress = address; order.Dispatch(); ... } 

... etc.

Is this normal, or do I have a wrong idea? I thought that each test should be independent, but how could I test Dispatch() without implicitly relying on CreateOrder and SetDeliveryAddress already passing?

And the second part of the question, if the approach described above looks fine, should I use a factory or something to create these objects in my test project? I'm not sure that there should only be test classes / methods in the test project, or is it normal to add a few helpers there.

+7
design c # unit-testing
source share
3 answers

You seem to be on the right track. In many unit tests, you will need to adjust the state of the object being tested in order to verify a specific part of the behavior. This will help a group of tests in classes when bahaviour testing requires a similar installation, and use the [TestInitialize] methods to reduce duplication of this installation.

eg:

 [TestClass] public class WhenReadyToDispatch{ private Order order; [TestInitialize] public void Initialize { order = <create an order> order.DeliveryAddress = <create an address> } [TestMethod] CanChangeOrderDeliveryAddress() { order.DeliveryAddress = address; } [TestMethod] CanDispatchAnOrder() { order.Dispatch(); } } 

It’s good that there are helper classes in the test project β€” you should be careful to check the code well-considered as your production code.

+8
source share

Your first question should be made with mocking and quenching , where do you create the fake order and address created from the interface of each class. Here's how you can simply test the submit method.

You could argue that the delivery method did the right thing by checking what happened to your fake (/ simulated stub) objects.

In response to the second part of your question; It is a good idea to have factory methods and even class hierarchies to make writing tests easier. It is also important to structure tests in a good way, as it is to structure production code.

+2
source share

I think part of your problem may be in the design of your order object. Trying to write a free test, only to find that it relies on other functions, usually indicates that they are not sufficiently untied. A few rules of thumb that may be relevant here:

If Order.DeliveryAddress is just a simple getter / setter, don't worry about testing it. This is similar to trying to prove that C # behaves as it should. There are few advantages for this. Conversely, if your dispatch test relies on this property, which is in working condition, is not really a dependency.

However, if Order.DeliveryAddress follows the logic, for example, ensuring that the address can only be changed for unmanaged orders, then this is more complicated. You probably do not want to try to submit the entire order to verify that Order.DeliveryAddress is no longer subject to change.

Invoking the principle of single responsibility (see 1 and 2 ) here will say that the Order class now does too much. This is both sending orders and enforcing the integrity of order data. In this case, you probably want to split the dispatching functionality into a DispatcherService, which simply takes the order and sends it, setting the IsDispatched flag in order in this process.

You can then test the DeliveryAddress behavior by simply setting the IsDispatched property accordingly.

The third approach (which is a kind of trick, but works well in situations where you are trying to get some testing on obsolete objects) is to subclass Order to create the TestableOrder class, which gives the test fixture the opportunity to tinker with the internal state of the class. In other words, it can produce a MarkAsDispatched () method that sets the internal flags of the IsDispatched classes and thus allows you to verify that DeliveryAddress is configured only before it is marked as sent.

Hope this helps.

+1
source share

All Articles