4

I am having a lot of trouble understanding how to unit test my web client.

I have just finished a project using TDD for the first time - this project hd no external dependencies such as API calls or databases, it was pure C# code. I definitely saw the benefits of using TDD and I would like to continue practising it.

My next project involves writing a SOAP client. I'm struggling to get past the first test which is using a simple IClient that logs in to the API successfully.

Here is the IClient interface:

public interface IClient
{
    bool IsLoggedIn { get; }
    bool Login(out string error);
}

I have no idea how I would go about testing this. I'm thinking the unit test method would be something like Login_WithValidCredentials_ReturnsTrue, but I'm not sure how I could do this without actually simulating every possible response from the API. Is this code actually unit testable, or should this be left to an integration test.

If anyone could give me an example of a simple unit test then I would be very grateful (I am using Moq).

1 Answer 1

2

Unit tests should run fast and have no external dependencies. Integration tests should cover methods that call web services.

You cannot unit test authentication logic on the client, you will have to do it on the server:

[WebMethod]
Authenticator{
 bool Login(Credentials credentials){
   return TestableClass.Login(credentials);
 }
}

now you can write a unit test on the server

Login_WithValidCredentials_ReturnsTrue(){
   // test TestableClass.login here
}

You can also test client side code that uses the service. say you have some code like this: (pardon my c#)

Class LoggerOnner{
  public LoggerOnner(IClient client, Response response){
    this.client = client
    this.page = page
  }

  Login() {
   if(this.client.Authenticate())
       response.sendPage("authenticated.aspx");
   else{
       response.sendError()
   }
  }
} 

You can test that it uses your Client correctly (how i imagine moc works :)

IClient mocClient= moq.Create(IClient).Authenticate( x-> return true );
Request moxRequest = moq.Create(Request);

LoggerOnner lo = new LoggerOnner(mocClient, mocRequest);

Assert( mocRequst.sendPage().calledWithArgs("authenticated.aspx"));

TLDR; don't unit test your Client class, make it small and test everything else

4
  • I don't understand how this can be tested though. What would I need to verify in the test for such a simple method (make request, check response, return true) ?
    – Sherlock
    Commented Dec 1, 2013 at 12:47
  • oh i see now that's the client your testing. Similar advice though, You cann't unit test the method that calls the web service so try and make that method as small as posible Commented Dec 1, 2013 at 13:02
  • 1
    @Eru: you can by stubbing out the webservice. The client needs to be tested to ensure that it properly passes the necessary information and reacts appropriately to the responses it receives. The stub class taking the role of the webservices can and should be as simple as possible, preferably without any further dependencies, as it sole goal is to support the testing of the client. In other words: where you w/should normally never rely on hard coded values, it is ok to do so in a test stub. Commented Dec 1, 2013 at 13:42
  • Oh ok, my C# missunderstanding, I thaught the Client object was the webservice. The second example shows stubbing out the client and testing the "LoggerOnner" code that uses the client. Commented Dec 2, 2013 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.