How to write a unit test for thread unsafe collection
I'm writing a doubly-linked list using TDD approach. This collection type is not thread safe. In order to implement the ICollection interface my list class must have several public properties (including IsSynchronized and SyncRoot which are used to provide a thread-safe way for collection using). The code of these two properties is pretty simple:
public bool IsSynchronized { get { return false; } }
private readonly object _syncRoot = new object();
public object SyncRoot { get { return _syncRoot; } }
The question is h开发者_开发技巧ow to write a correct unit test for it. This test should check the right usage and incorrect usage either.
my list class must have several public properties (including IsSynchronized and SyncRoot
It doesn't. This dates back to .NET version 1 and is widely considered a giant mistake. It created a false sense of thread-safety that got a lot of programmers in deep trouble. Such a class wasn't actually thread-safe in all cases, iterating for one wasn't. It was completely dropped in the .NET 2.0 generic collection classes. And you should not implement ICollection, a modern collection class should be generic and implement ICollection<T>
. That unfortunately still requires implementing IEnumerable, a legacy we'll probably never get rid of. You implement it with an explicit implementation, such methods are not public.
A secondary consideration is whether implementing ICollection<> is a good idea. A linked list makes a member like Count expensive, it is O(n) by nature. You need to track the number of elements in the list separately to make it O(1). The .NET LinkedList<> class, also a doubly linked-list collection class, does do this.
I'd say this falls into the category of not your responsibility. The SyncRoot
property is there in case someone using your collection class wants to synchronize reads/writes, providing a convenient object to lock on—nothing more. (In fact the purpose of this property was widely misunderstood; the property itself is often regarded as rather useless, as Hans has pointed out.)
If you do feel you have sufficient reason to implement this interface, it is still the case that synchronization is entirely outside the scope of your type itself (as you have signaled by having the IsSynchronized
property return false
); as such it shouldn't really need to be unit tested on your end.
In fact, I believe it's quite common for implementors of the ICollection
interface to simply ignore the SyncRoot
property (set it to null
). That should tell you something.
For a unit test, you could simply verify that the SyncRoot
property is not null
.
精彩评论