Imagine a function like this:
private static ConcurrentList<object> list = new ConcurrentList<object>();
public void Add(object x)
{
Task.Factory.StartNew(() =>
{
list.Add(x);
}
}
I don't care WHEN exactly the fentry is added to the list, but i need it to be added in the end ( obviously ;) )
I don't see a way to properly unittest stuff like this without returning any callback-handler or sth. and therefor adding logic that's not required for the program
How would you do it?
The AAA (Arrange-Act-Assert) pattern has become almost a standard across the industry. It suggests that you should divide your test method into three sections: arrange, act and assert.
One way to do this is to make your type configurable such that it takes a TaskScheduler
instance.
public MyCollection(TaskScheduler scheduler) {
this.taskFactory = new TaskFactory(scheduler);
}
public void Add(object x) {
taskFactory.StartNew(() => {
list.Add(x);
});
}
Now in your unit tests what you can do is create a testable version of TaskScheduler
. This is an abstract class which is designed to be configurable. Simple have the schedule function add the items into a queue and then add a function to manually do all of the queue items "now". Then your unit test can look like this
var scheduler = new TestableScheduler();
var collection = new MyCollection(scehduler);
collection.Add(42);
scheduler.RunAll();
Assert.IsTrue(collection.Contains(42));
Example implementation of TestableScehduler
class TestableScheduler : TaskScheduler {
private Queue<Task> m_taskQueue = new Queue<Task>();
protected override IEnumerable<Task> GetScheduledTasks() {
return m_taskQueue;
}
protected override void QueueTask(Task task) {
m_taskQueue.Enqueue(task);
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) {
task.RunSynchronously();
}
public void RunAll() {
while (m_taskQueue.Count > 0) {
m_taskQueue.Dequeue().RunSynchronously();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With