Я написал реализацию для нужной мне приоритетной очереди, и теперь я хотел бы протестировать ее. Я решил использовать moq, так как я уже использовал moh rhino на работе и хочу попробовать что-то новое / возможно, более простое.
Интерфейс для моего PriorityQueue довольно прост:
public interface IPriorityQueue<TKey, TValue> where TKey : IComparable
{
void Enqueue(TKey priority, TValue value);
bool IsEmpty();
TValue Peek();
TValue Dequeue();
}
Я отправился написать свой первый тест, который проверяет метод Enqueue. Вот реализация для этого:
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 });
}
}
Первый модульный тест, который я написал, состоял в том, чтобы проверить, был ли ключ пустым, он должен выдавать исключение аргумента пустое.
[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();
}
Итак, теперь я понимаю, что мой метод Enqueue никогда не будет вызываться, потому что я создаю экземпляр экземпляра моего интерфейса, а не реализацию. Тогда возникает вопрос, а если я должен протестировать с использованием своих интерфейсов (по крайней мере, такое впечатление я получил после просмотра TDD - Понимание Mock Objects Роя Ошерова), как мне это сделать? проверить мою реализацию?
Неужели я не правильно понял совет по тестированию интерфейсов?
В видео он создал класс в тесте, который он писал, и использовал его для тестирования. Я не понимаю, как это помогло бы мне проверить мою реализацию PriorityQueue (в частности, метод Enqueue).
Спасибо, переполнение стека!
edit: Вот следующий (безобразный) рабочий тест, который я придумал. Я крайне недоволен этим, это кажется таким примитивным. Кто-нибудь может предложить лучший способ сделать это? Из приведенных ниже ответов кажется, что для этого модульного теста рамки совершенно не нужны.
Однако вот оно:
[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);
}