Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object instantiation in Test Classes

I'm using MS UnitTesting and trying to find my way around writing my first unit tests. It seems like all my unit tests start off with creating the same few 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 have I got the wrong idea? I kind of thought every test was supposed to be independent, but how would it be possible to test Dispatch() without that implicitly relying on CreateOrder and SetDeliveryAddress already passing?

And the second part of the question, if the above approach looks ok, should I be using a factory or something to instantiate these objects in my test project? I'm not sure if a test project should only contain test classes/methods, or it's ok to add a bunch of helpers in there too.

like image 218
fearofawhackplanet Avatar asked Jun 04 '10 11:06

fearofawhackplanet


People also ask

What do you mean by object instantiation?

An instance of an object can be declared by giving it a unique name that can be used in a program. This process is known as instantiation. A class can also be instantiated to create an object, a concrete instance of the class. The object is an executable file that can run on a computer.

Can we create a object for a test class in Java?

Most Java unit tests consist of a Class Under Test (CUT), and possibly dependencies or collaborators. The CUT, dependencies and collaborators need to be created somewhere. Some people create each object using 'new' (vanilla construction), others use patterns such as Test Data Builders or Object Mother.

Why do we instantiate an object?

Instantiation allocates the initial memory for the object and returns a reference. An instance is required by non-static methods as they may operate on the non-static fields created by the constructor.

What is an instantiation of a class?

Note: The phrase "instantiating a class" means the same thing as "creating an object." When you create an object, you are creating an "instance" of a class, therefore "instantiating" a class. The new operator requires a single, postfix argument: a call to a constructor.


2 Answers

You seem to be on the right track to me. In a lot of unit tests you will need to set up the state of the object you are testing in order to be able to test a particular part of behaviour. It will help to group tests in classes when the bahaviour you are testing requires similar setup, and to use [TestInitialize] methods to reduce the duplication of that setup.

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 fine to have helper classes in the test project - you should be aiming to make you test code well factored as your production code.

like image 88
Jonny Cundall Avatar answered Oct 10 '22 18:10

Jonny Cundall


Your first question is to do with mocking and stubbing where you create a fake order and address created from the interface of each class. This is how you can then just be testing the Dispatch method.

You can then assert that the dispatch method did the right thing by checking what happened to your fake (stub/mock) objects.

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

like image 23
Dave Arkell Avatar answered Oct 10 '22 17:10

Dave Arkell