Search code examples
asp.netunit-testingtestingwebformsmvp

why would I unit test business layer in MVP


i created the following sample method in business logic layer. my database doesn't allow nulls for name and parent columns:

public void Insert(string catName, long catParent)
{
    EntityContext con = new EntityContext();
    Category cat = new Category();
    cat.Name = catName;
    cat.Parent = catParent;
    con.Category.AddObject(cat);
    con.SaveChanges();
}

so i unit test this and test for empty name and empty parent will fail. to get around that issue i have to refactor the Insert mathod as following:

public void Insert(string catName, long catParent)
{
    //added to pass the test
    if(string.IsNullOrEmpty(catName)) throw new InvalidOperationException("wrong action. name is empty.");
    long parent;
    if(long.TryParse(catParent, out parent) == false) throw new InvalidOperationException("wrong action. parent didn't parsed.");
    //real bussiness logic
    EntityContext con = new EntityContext();
    Category cat = new Category();
    cat.Name = catName;
    cat.Parent = parent;
    con.Category.AddObject(cat);
    con.SaveChanges();
}

my entire bussiness layer are simple calls to database. so now i'm validating the data again! i already planned to do my validation in UI and test that kind of stuff in UI test units. what should i test in my bussiness logic method other than validation related tasks? and if there is nothing to be unit tested why everybody says "unit test all the layers" and things like that which i found a lot online?


Solution

  • The techniques involved in testing are those that you break down your program into smaller parts (smaller components or even classes) and test those small parts. As you assemble those parts together, you make less comprehensive tests -- the smaller parts are already proven to work -- until you have a functional, tested program, which then you give to users for "user tests".

    It's preferable to test smaller parts because:

    1. It's simpler to write the tests. You'll need less data, you only setup one object, you have to inject less dependencies.

    2. It's easier to figure out what to test. You know the failing conditions from a simple reading of the code (or, better yet, from the technical specification).

    Now, how can you guarantee that you business layer, simple as it's, is correctly implemented? Even a simple database insert can fail if badly written. Besides, how can you protected yourself from changes? Right know, the code works, but what will happen in the future if the database is changed or someone update the business logic.

    However, and this is important, you actually don't need to test everything. Use your intuition (which is also called experience) to understand what needs testing and what doesn't. If you method is simple enough, just make sure the client code is correctly tested.

    Finally, you've said that all your validation will occur in the UI. The business layer should be able to validate the data in order to increase reuse in your application. Fail to do that and whenever you or whoever make changes in your code in the future might create new UI and forget to add the required validations.