Click here to Skip to main content
15,892,298 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have an existing asp.net web services service layer which does not have any sort of unit testing happening. My manager has decide to introduce a unit testing layer to test the projects. Side by side the whole web service is moving to a newer technology i.e. asp.net web api. I want to create a common infratructure which can later be used for unit testing web apis as well. Is that possible? If yes, how can I proceed with this?

What I have tried:

I do not have any idea if this can be achieved. I have tried searching on internet for some clue but could not find anything.
Posted
Updated 4-Mar-16 5:28am
Comments
Gautham Prabhu K 4-Mar-16 7:41am    
Yes you can if your existing service layer is designed properly for unit testing
, I am sure you can use same unit test with little or no modification.

The Unit test is suppose test you business logic and not your infrastructure.
Krati Garg 4-Mar-16 8:30am    
Could you please explain a little further on properly designing the service layer for unit testing? In my existing service layer which was created by some other team a long time ago all the logic including connection to database is written in webmethods. I am supposed to refactor the code to make it more testables. There are no interfaces involved as of now. I need to know what a properly desined service layer is.
Dave Kreskowiak 4-Mar-16 8:01am    
Yeah, if your service code was written properly to being with there is no "infrastructure" to create to do the unit testing. Unit testing doesn't have anything to do with how to get at the methods you're testing. It's for testing the methods themselves.

If you're code wasn't written against interfaces, you've got a much bigger problem than just building an infrastructure you don't need.
Krati Garg 4-Mar-16 8:33am    
The service layer was created by some other team a long time ago. It does not have any interfaces and it has all the connections to database inside of webmethods. I need to refactor the code to make it testable. Could you please suggest good practices to achieve that?
Dave Kreskowiak 4-Mar-16 9:22am    

1 solution

First of all you need to understand what unit testing is. Unit testing is when you test the logic, you don't use databases, services or anything like that, it only tests the logic. If the project is not written to be unit testable then the chances of it being testable are almost zero and will require a lot of refactoring. Let's say you have a bank web service with a Transfer method

C#
[WebMethod]
public bool Transfer(decimal amount, string sourceAccount, string destinationAccount)
{
    // code here that accesses the database
    // and executes SQL to remove from one account
    // and add to another

    return true;
}


This is probably what you have at the moment so what you need to do is create a class that handles the logic and a class that handles the data access.

C#
public interface IBank
{
    bool Subtract(decimal amount, string account);
    bool Add(decimal amount, string account);
}


C#
public class Bank : IBank
{
    public bool Subtract(decimal amount, string account)
    {
        // your data access code will go here

        return true;
    }

    public bool Add(decimal amount, string account)
    {
        // your data access code will go here

        return true;
    }
}


And the class with the business logic

C#
public class BankService
{
    private IBank bank;

    // you'll probably use an IOC container for this
    public BankService() : this(new Bank())
    {
    }

    public BankService(IBank bank)
    {
        this.bank = bank;
    }

    public bool Transfer(decimal amount, string sourceAccount, string destinationAccount)
    {
        this.bank.Subtract(amount, sourceAccount);
        this.bank.Add(amount, destinationAccount);

        return true;
    }
}


It is this class and this class only we'll be unit testing. Update your web method to use this class instead of having the code inside the webmethod

C#
[WebMethod]
public bool Transfer(decimal amount, string sourceAccount, string destinationAccount)
{
    BankService bs = new BankService();
            
    return bs.Transfer(amount, sourceAccount, destinationAccount);
}


So the webmethod uses BankService and that is where the transfer logic is, and that BankService uses Bank to do the database updates. The logic we need to test is that when transferring money the money is subtracted from one and added to the other, so we'll mock the IBank class (I'm using moq in this example) so that we don't need the database and there is no database access and we'll test that the appropriate methods have been called, so the unit test will look like this

C#
Mock<IBank> bank = new Mock<IBank>();

BankService bankService = new BankService(bank.Object);
bankService.Transfer(10, "111", "222");

bank.Verify(b => b.Subtract(10, "111"));
bank.Verify(b => b.Add(10, "222"));


That's the basics of what it is you need to do, you need to break things into classes that do dedicated tasks and have those tasks implement interfaces so that they can be mocked at any level. In reality your BankService class itself would implement IBankService in case you needed to mock the entire thing.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900