Question

Pre-story: I am testing a service. Every n seconds it starts some processes and runs some jobs. I want to cover the top level of this service (a class which is inherited from ServiceBase) with an integration test. My goal is to verify: 1. that I can start it, 2. that it sets all timers and 3. creates Job Management Objects to execute jobs (at least to see one execution on the timer). In the future we want to increase the performance by moving different jobs into different threads, which will also increase complexity of the code.(this is another reason to test it now, while it is still pretty simple)

The question itself: How should I test a service? All methods and properties in this class are protected or private. And with RhinoMocks I can only stub public members.

Some more thoughts: There is a private member AppJobManagement in this class, which I want to stub. I don't want to use the real instance of this class, as it is connected to the database and may do a lot of unwanted changes when running. I could make it public for stubbing.

But the next issue I have, is how can I assert that the service class works correctly? I will need again make public the methods under the test. And this is what I would like to avoid.

Any advice is highly appreciated!

Was it helpful?

Solution

You can create a public or internal constructor to take a dependency on AppJobManagement. If you can, change the reference to an interface for this class as it may make testing easier.

public class ServiceToBeTested : ServiceBase
{
    private IAppJobManagement _appJobManagment;

    public ServiceToBeTested()
    {
        _appJobManagment = new AppJobManagement();
    }

    internal ServiceToBeTested(IAppJobManagement appJobManagment)
    {
        _appJobManagment = appJobManagment;
    }
}

If the ServiceToBeTested has a number of protected methods you would like to mock/fake, you should consider another dependency. For example, instead of:

public void DoSomethingImportant(string foo)
{
    if (someCondition)
    {
        DoThisOneWay(foo);
    }
    else
    {
        DoThisDifferently(foo);
    }
}

protected void DoThisOneWay(string foo) {}
protected void DoThisDifferently(string foo) {}

You can use another object:

public interface IServiceWorker
{
    void DoThisOneWay(string foo);
    void DoThisDifferently(string foo);
}

public void DoSomethingImportant(string foo)
{
    if (someCondition)
    {
        _worker.DoThisOneWay(foo);
    }
    else
    {
        _worker.DoThisDifferently(foo);
    }
}

The IServiceWorker _worker would be easily mocked.

Update

Another pattern is to use a Factory class to generate these objects.

public interface IAppJobManagementFactory
{
    IAppJobManagement Create(string arg1, int arg2);
}

This too can be mocked.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top