4

I have a class in .NET which creates and starts a new System.Threading.Tasks.Task as follows:

public class ScheduledTask
{
    private IFoo _foo;

    public ScheduledTask(IFoo foo)
    {
        _foo = foo;
    }

    public void Start()
    {           
        _task = new Task(() => Run());
        _task.Start();
    }

    public void Stop(TimeSpan timeout)
    {
        var taskCompletedNormally = _task.Wait(timeout);
        if (taskCompletedNormally)
        {                
            _task.Dispose();
            _task = null;                
        }
    }

    private void Run(){ // Do some work}
}

How do I unit test the ScheduledTask.Start and ScheduledTask.Stop methods in C#.Net? Which are the frameworks available for such unit tests and which are the best practices for unit testing threading (or task parallelism)?

4

2 に答える 2

5

Your class is doing to much. Start/stop is a generic function that should be in its own class.

public class StartStopTask
{
    private readonly Action _action;

    public StartStopTask(Action action)
    {
        _action = action;
    }

    public void Start()
    {           
        _task = new Task(_action);
        _task.Start();
    }
    ...
}

This class is easy to unit test.

bool worked = false;
var startstop = new StartStopTask(() => { worked = true });
startstop.Start();
startstop.Stop(new TimeSpan(0,0,0,10));
Assert.That(worked, Is.True);

Your other classes then uses the StartStopTask to do its work.

Either derive

public class ScheduledTask : StartStopTask
{
    private IFoo _foo;

    public ScheduledTask(IFoo foo)
        : base(() => Run())
    {
        _foo = foo;
    }

    private void Run(){ // Do some work }
}

Or just delegate the work

public class ScheduledTask
{
    private IFoo _foo;
    private readonly StartStopTask _startstop;

    public ScheduledTask(IFoo foo)
    {
        _foo = foo;
        _startstop = new StartStopTask(() => Run());
    }

    public void Start()
    {           
        _startstop.Start();
    }

    public void Stop(TimeSpan timeout)
    {
        _startstop.Stop(timeout);
    }

    private void Run(){ // Do some work }
}

Even better would be to just let Run be a public method and let the caller decide how it should be run.

于 2012-05-25T11:53:09.373 に答える
0

You can try with Mock task.

Best !

于 2012-05-25T11:00:08.483 に答える