I wrote an implementation for a priority queue I needed, and now I would like to test it. I decided on using moq, as I’ve already used rhino mocks at work and want to try something new/possibly easier.
The interface for my PriorityQueue is pretty straight-forward:
public interface IPriorityQueue<TKey, TValue> where TKey : IComparable
{
void Enqueue(TKey priority, TValue value);
bool IsEmpty();
TValue Peek();
TValue Dequeue();
}
I went to write my first test, which tests the Enqueue method. Here’s the implementation for it:
public void Enqueue(TKey priority, TValue value)
{
if (priority == null) { throw new ArgumentNullException("priority"); }
if (_queue.ContainsKey(priority))
{
// queue contains key, therefore just add value to existing key's list
_queue[priority].Add(value);
}
// otherwise just add pair
else
{
_queue.Add(priority, new List<TValue>() { value });
}
}
The first unit test I wrote was to test if the key was null, it should throw an argument null exception.
[TestMethod]
public void EnqueueNullKey_ThrowsArgumentNullException()
{
/* Arrange */
var mock = new Mock<IPriorityQueue<string, IMessage>>();
// string implements the IComparable interface, and is nullable.
mock
.Setup(x => x.Enqueue(null, It.IsAny<IMessage>()))
.Throws<ArgumentNullException>();
/* Assert */
mock.VerifyAll();
}
So I realize now, that my method Enqueue will never be called, because I am instantiating an instance of my interface, not the implementation. Then the question begs to be asked, if I’m supposed to test with using my interfaces (at-least that was the impression I got after watching Roy Osherove’s TDD – Understanding Mock Objects video) how am I to test my implementation?
Am I misunderstanding the advice to test with interfaces?
In the video he created a class within the test he was writing, and used that to test. I don’t see how that would help me test my implementation of PriorityQueue (specifically the Enqueue method).
Thanks stack overflow!
edit: Here’s the following (ugly) working test that I’ve came up with. I’m extremely unhappy with it, it feels so primitive. Can anyone suggest a better way of doing this? From the responses below, it seems like the framework is completely unnecessary for this unit test.
However, here it is:
[TestMethod]
public void EnqueueNullKey_ThrowsArgumentNullException()
{
/* Arrange */
var pq = new PriorityQueue<string, IMessage>();
try
{
pq.Enqueue(null, null);
}
catch(ArgumentNullException)
{
Assert.IsTrue(true);
return;
}
// failure condition if we don't catch the exception
Assert.IsTrue(false);
}
You are getting it wrong. You don’t need a mock of
IPriorityQueuewhen you are testing methods on one of its implementation. What you need is a mock ofqueueThe responsibilities of
Enqueuemethod areFor #1 testing is quite easy and a stub implementation of
queuewill suffice, for #2 and #3 you will need a mock ofqueue. For #2 and #3 you should test if mock queue’s Add methods is called with correct parameters