user320478
user320478

Reputation: 155

Unit testing Code which use API

I have this simple method which calls the TFS (Team foundation server) API to get WorkItemCollection object. I have just converted in to an entity class and also added it in cache. As you can see this is very simple.

How should i unit test this method. Only the important bit it does is calls TFS API. Is it worth testing such methods? If yes then how should we test it?

One way I can think is I can mock call to Query.QueryWorkItemStore(query) and return an object of type “WorkItemCollection” and see finally this method converts “WorkItemCollection” to List. And check if it was added to cache or not.

Also as I am using dependency injection pattern her so I am injecting dependency for

Should I only pass dependency of mocked type (Using MOQ) or I should pass proper class type.

public virtual List<Sprint> Sprint(string query)
{
    List<Sprint> sprints = 
        Cache.Get<List<Sprint>>(query);

    if (sprints == null)
    {
        WorkItemCollection items = 
            Query.QueryWorkItemStore(query);
        sprints = new List<Sprint>();

        foreach (WorkItem i in items)
        {
            Sprint sprint = new Sprint
            {
                ID = i.Id,
                IterationPath = i.IterationPath,
                AreaPath = i.AreaPath,
                Title = i.Title,
                State = i.State,
                Goal = i.Description,
            };

            sprints.Add(sprint);
        }

        Cache.Add(sprints, query, 
            this.CacheExpiryInterval);
    }

    return sprints;
}

Upvotes: 1

Views: 396

Answers (1)

Wim Coenen
Wim Coenen

Reputation: 66753

Should I only pass dependency of mocked type (Using MOQ) or I should pass proper class type.

In your unit tests, you should pass a mock. There are several reasons:

  • A mock is transparent: it allows you to check that the code under test did the right thing with the mock.
  • A mock gives you full control, allowing you to test scenarios that are difficult or impossible to create with the real server (e.g. throw IOException)
  • A mock is predictable. A real server is not - it may not even be available when you run your tests.
  • Things you do on a mock don't influence the outside world. You don't want to change data or crash the server by running your tests.
  • A test with mocks is faster. No connection to the server or real database queries have to be made.

That being said, automated integration tests which include a real server are also very useful. You just have to keep in mind that they will have lower code coverage, will be more fragile, and will be more expensive to create/run/maintain. Keep your unit tests and your integration tests separate.

edit: some collaborator objects like your Cache object may also be very unit-test friendly. If they have the same advantages as that of a mock that I list above, then you don't need to create a mock. For example, you typically don't need to mock a collection.

Upvotes: 3

Related Questions