4

У меня есть класс в .NET, который создает и запускает новый System.Threading.Tasks.Task следующим образом:Как модульное тестирование для параллелизма задач

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} 
} 

Как блок тестирование ScheduledTask.Start и ScheduledTask.Stop методы в C# .NET? Каковы рамки, доступные для таких модульных тестов и которые являются наилучшей практикой для потоковой обработки единичного тестирования (или параллелизма задач)?

ответ

5

Ваш класс делает много. Start/stop - это общая функция, которая должна быть в своем классе.

public class StartStopTask 
{ 
    private readonly Action _action; 

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

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

Этот класс прост в тестировании.

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

Ваши другие классы затем используют StartStopTask для выполнения своей работы.

Либо получить

public class ScheduledTask : StartStopTask 
{ 
    private IFoo _foo; 

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

    private void Run(){ // Do some 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 } 
} 

Еще лучше было бы просто позволить Run быть открытым способом, и пусть вызывающий решить, как он должен быть запущен.

0

Вы можете попробовать выполнить Mock task.

Лучшее!

Смежные вопросы