Here few basic rules:
I. public void
A testing method is always void.
II. name contains the methodname we want to test + scenario + expected behaviour.
As follow: methodNameWewantToTest_Scenario_Expectedbehavior()
Here below the structure that follows the testing method body
[Test]
public void CanBeCancelledBy_UserIsAdmin_ReturnsTrue()
{
var reservation = new Reservation(); //Arrange is where we initalize the object
var result = reservation.CanBeCancelledBy(new User{IsAdmin = true }); //Act the method we are going to test
Assert.IsTrue(result); //Assert
}
Depending on what we want to test we might adopt a different approach.
The above code is also known as State-Based testing because we test the state changes of the applications.
Sometimes we have to deal with external resources and we need to verify that the class we are testing interacts with another class properly. This is what we call
Interaction Testing.
In the example here below the orderService should store the order in a external storage (database or cloud)
public class OrderService
{
public void PlaceOrder(Order Order)
{
_storage.Store(Order):
...
}
}
So what we are going to test is that the OrderService object is interacting properly with the storage object property.
We'll do this checking that our code calls the store method of the storage object with the right argument.
Is better to reserve the Interaction testing approach only for dealing with external resources; this because with interaction testing, your tests start to couple
during the implementation.
What need to be asserted is just to verify that the right method is called with the right argumnents.
As you refactor and restrcture your code, it is possible you move some of these methods around, doing that you may break one or more tests.
It is worthy to emphasize, that your test shoud test the external behaviour and not the implementation, therefore prefer statebased testing to interaction testing;
and use interaction testing only when dealing with external resources.
[TestFixture]
public class OrderServiceTests
{
[Test]
public void PlaceOrder_WhenCalled_StoreTheOrder()
{
// Arrange
var storage = new Mock<IStorage>();
var service = new OrderService(storage.Object);
var order = new Order();
// Act
service.PlaceOrder(order);
// Assert
storage.Verify(s => s.Store(order));
}
}
We are programming the mock object with storage.Verify(s => s.Store(order));.
In order to test the interaction between 2 objects we use the .Verify() method of mock object.
In this way we are testing if any given method is called with the right arguments or not.