7

I'm new to Unit Tests so I've been trying to code some examples to learn the right way to use them. I have an example project which uses Entity Framework to connect to a database.

I'm using an n-tier architecture composed by a data access layer which queries the database using EF, a business layer which invokes data access layer methods to query database and perform its business purpose with the data retrieved and a service layer which is composed of WCF services that simply invoke business layer objects.

Do I have to code unit tests for every single layer (data access, business layer, services layer?

Which would be the right way to code a unit test for a method that queries a database? The next code is an example of a method in my data access layer which performs a select on the database, how should its unit test be like?

public class DLEmployee
{

    private string _strErrorMessage = string.Empty;
    private bool _blnResult = true;

    public string strErrorMessage
    {
        get
        {
            return _strErrorMessage;
        }
    }
    public bool blnResult
    {
        get
        {
            return _blnResult;
        }
    }

    public Employee GetEmployee(int pintId)
    {
        Employee employee = null;
        _blnResult = true;
        _strErrorMessage = string.Empty;

        try
        {
            using (var context = new AdventureWorks2012Entities())
            {
                employee = context.Employees.Where(e => e.BusinessEntityID == pintId).FirstOrDefault();
            }
        }
        catch (Exception ex)
        {
            _strErrorMessage = ex.Message;
            _blnResult = false;

        }

        return employee;
    }
razp26
  • 191
  • 3
  • 17
  • 1
    You're going to have options with trade offs starting with a mocking framework. Others will setup test databases that are somehow restored or use transactions that rollback in the tear down. See here http://stackoverflow.com/questions/22690877/how-are-people-unit-testing-with-entity-framework-6-should-you-bother – Steve Greene Aug 10 '15 at 17:32
  • Thanks for the link, took me to a great tutorial of mocking entity framework when unit testing http://www.asp.net/web-api/overview/testing-and-debugging/mocking-entity-framework-when-unit-testing-aspnet-web-api-2 – razp26 Aug 11 '15 at 15:03

2 Answers2

9

Here are my 2 cents based on Domain Driven Design principles:

  • Your business layer should not depend on the concrete data layer, it should just define some abstract interfaces that the data layer can implement (repositories).
  • You should definitely unit-test your business layer with a fake data layer that does not touch the file system.
  • You might create integration tests including your service and business layer with a fake data layer. There is no point mocking out the business layer and check what the service layer calls on the business layer (behavior testing), rather check what state changes it makes on the business objects that are observable through the business layer.
  • You should create some end-to-end tests with a real data layer, the service and business layer and exercise some use-cases on the service layer.

If you just started on unit testing, I advise you to read Kent Beck's Test Driven Development by Example and Gerard Meszaros' xUnit Test Patterns

wigy
  • 2,174
  • 19
  • 32
  • 1
    +1 great answer. I agree with you, there's no point in unit testing all layers but you definitely need the business layer fully tested. Though I would add to only mock the outside communication with the business layer and not mock every layer inside the business layer. – Kurtis Aug 10 '15 at 20:19
1

I would have to say yes it is necessary to unit test every single layer. By doing so will give better coverage. The maintenance portion of it can be challenging since you will end up with lots of unit test cases however it does help avoid huge pitfalls when someone try to break some very important logic. It is best to have the unit test for all the layers be automated using a continuous integration tool such as Jenkins.

As for your example on the database layer for unit testing, keep it simple like what you have and assert based on the meta data such as required field, size of cell data and etc.

otaku
  • 964
  • 5
  • 16