Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write an integration test in NUnit?

We are two students writing our bachelor thesis and we have developed a Windows Application, which should be able to aid a restaurant in various communication processes. Fundamentally, it should be able to present information about the order from the moment a guest send it to it is served.

We have omitted to test during the development but have decided to write unit tests now. Nevertheless, we have found out that the most suitable test we can write to our system now are integration tests because all the methods in our classes are bound to SQL stored procedures via LINQ to SQL. We are aware of the usage of stubs to fake out a dependency to a database, but when our database already is implemented together with all the functions, we figured it would give us more value to test several methods together as an integration test.

As seen in the code below we have tried to follow the guide lines for a unit test, but is this the right way to write an integration test?

[Test]
public void SendTotalOrder_SendAllItemsToProducer_OneSentOrder()
{
    //Arrange
    Order order = new Order();
    Guest guest = new Guest(1, order);
    Producer producer = new Producer("Thomas", "Guldborg", "Beverage producer");            
    DataGridView dataGridView = new DataGridView { BindingContext = new BindingContext() };
    order.MenuItemId = 1;
    order.Quantity = 1;

    //Act
    guest.AddItem();
    dataGridView.DataSource = guest.SendOrderOverview();
    guest.SendOrder(dataGridView);
    dataGridView.DataSource = producer.OrderOverview();
    var guestTableOrder = producer.OrderOverview()
        .Where(orders => orders.gtid == guest.GuestTableId)
        .Select(producerOrder => producerOrder.gtid) 
        .Single();

    //Assert
    Assert.That(guestTableOrder, Is.EqualTo(guest.GuestTableId));
}
like image 710
Guldborg92 Avatar asked May 14 '15 07:05

Guldborg92


1 Answers

Yes, generally speaking, this is how to write a unit test/integration test. You observe some important guidelines:

  • Distinct Act-Arrange-Assert steps
  • The test name describes these steps (maybe it should have something like "ShouldSendOneOrder" at the end, "Should" is commonly used to describe the Assert).
  • One Assert per test.

I assume you also obey other guidelines:

  • Tests are independent: they don't change persistent state, so they don't influence other tests.
  • Test realistic use cases: don't arrange constellations that violate business logic, don't do impossible acts. Or: mimic the real application.

However, I also see things that raise eyebrows.

  • It's not clear which act you test. I think some "acts" belong to the arrange step.

  • A method like producer.OrderOverview() makes me suspect that domain objects execute database interaction. If so, this would violate persistence ignorance. I think there should be a service that presents this method (but see below).

  • It's not clear why dataGridView.DataSource = producer.OrderOverview(); is necessary for the test. If it is, this only aggravates the most serious point:

  • Business logic and UI are entangled!!

    • Method like guest.SendOrderOverview() and producer.OrderOverview() are smelly: why should a domain object know how to present its content? That's something a presenter (MVP) or a controller (MVC) or a view model (MVVM) should be responsible for.
    • A method like guest.SendOrder(dataGridView) is evil. It ties the domain layer to the UI framework. This fixed dependency is evil enough, but of course you also need values from the grid view inside this method. So the business logic needs intimate knowledge of some UI component. This violates the tell - don't ask principle. guest.SendOrder should have simple parameters that tell it how to do its task and the domain shouldn't have any reference to any UI framework.

You really should address the latter point. Make it your goal to run this test without any interaction with DGV.

like image 134
Gert Arnold Avatar answered Nov 14 '22 12:11

Gert Arnold