tags:

views:

86

answers:

3

I'm trying to follow TDD (i'm newbee) during development of Service class which builds tasks passed by Service clients. The built objects are then passed to other systems. In other words this service takes tasks but returns nothing as a result - it passes built tasks to other Services. So I'm wondering how can I write test for it because there is nothing to assert. I'm thinking about using mocks to track interactions inside the service but I'm a little bit afraid of using mocks because I will be tied up with internal implementarion of the service.

Thanks all of you in advance!

+2  A: 

There's no problem using mocks for this, since you are effectively going to be mocking the external interface of the components that are used internally in the component. This is really what mocking is intended for, and sound like a perfect match for your use case.

When doing TDD it should also allow you to get those quick turnaround cycles that are considered good practice, since you can just create mocks of those external services. These mocks will easily allow you to write another failing test.

krosenvold
+1  A: 

You can consider breaking it up in a couple classes. One responsible to build the list of tasks that will be executed, and the other responsible to execute the list of tasks it is handed. This way you can directly test the code that build the lists of tasks.

That said, I want to add a sample I posted on another question, regarding how I view the TDD process when external systems are involved.

Lets say you have to check whether some given logic sends an email, logs the info on a file, saves data on the database, and calls a web service (not all at once I know, but you start adding tests for each of those). On each test you don't want to hit the external systems, what you really want to test is if the logic will make the calls to those systems that you are expecting it to do. So when you write a test that checks that an email is sent when you create an user, what you test is if the logic calls the dependency that does that. Notice that you can write these tests and the related logic, without actually having to implement the code that sends the email (and then having to access the external system to know what was sent ...). This will help you focus on the task at hand and help you get a decoupled system. It will also make it simple to test what is being sent to those systems.

eglasius
A: 

Not sure what language you're using so in psuedo-code it could be something like this:

when_service_is_passed_tasks
  before_each_test
    mockClients = CreateMocks of 3 TaskClients
    tasks = GetThreeTasks()
    myService = new TaskRouter(mockClients)

  sends_all_to_the_appropriate_clients
    tasks = GetThreeTasks()
    myService.RouteTaks(tasks)
    Assert mockClients[0].AcceptTask(tasks[0]) was called
    Assert mockClients[1].AcceptTask(tasks[1]) was called
    Assert mockClients[2].AcceptTask(tasks[2]) was called

  if_one_routing_fails_all_fail
    tasks = GetTasksWhereOneIsFailing()
    myService.RouteTaks(tasks)
    Assert mockClients[0].AcceptTask(*) was not called
    Assert mockClients[1].AcceptTask(*) was not called
    Assert mockClients[2].AcceptTask(*) was not called
George Mauer