Я тестирую демо-приложение, которое является клиентом POP3. Клиент POP3 реализует IDisposable
, поэтому я пытаюсь проверить цикл using
.
(Я использую nunit 2.5.2 и Moq 4.0)
/// <summary>
/// Unsuccessful construct dispose cycle, no ILogger object given.
/// Expecting ArgumentNullException. Expecting TcpClient dispose to be called.
/// </summary>
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ConstructorDispose_LoggerNull_ArgumentNullException()
{
mockTcpClient.Setup(x => x.Dispose());
using (var popClient = new PopClient(null, mockTcpClient.Object))
{
}
mockTcpClient.VerifyAll();
}
Как вы можете видеть, метод verifyAll
никогда не будет вызываться, и тест будет успешным, тем не менее. Итак...
Обновление. Я исправил его так:
mockTcpClient.Setup(x => x.Dispose());
var correctExceptionThrown = false;
try
{
using (var popClient = new PopClient(null, mockTcpClient.Object))
{
}
}
catch (ArgumentNullException)
{
correctExceptionThrown = true;
}
finally
{
mockTcpClient.VerifyAll();
}
Assert.That(correctExceptionThrown);
Но dispose не называется, кажется, является спецификацией С#.
mockTcpClient.Setup(x => x.Dispose());
try
{
using (var popClient = new PopClient(null, mockTcpClient.Object))
{
}
}
finally
{
mockTcpClient.VerifyAll();
}
Это не отвечает на ваш вопрос (как он уже решил), но он все равно стоит и стоит публиковать.
[ExpectedException] - довольно верный способ проверить исключения. Он может быть подвержен ошибкам, поскольку неправильная строка может инициировать исключение ожидаемого типа, что приводит к ошибочному проходу. Я бы настоятельно рекомендовал вам проверить Assert.Throws() вместо:)
Лучше использовать (вы можете запросить возвращаемое исключение), более читаемым и, прежде всего, более безопасным.
Вы уже обнаружили, что на самом деле dispose действительно not, если конструктор терпит неудачу. Но могут быть и другие случаи, когда вы можете проверить свои mocks после того, как будет выбрано ожидаемое исключение. Я просто делаю это в тесте TearDown следующим образом:
[SetUp]
public void SetUp()
{
this.mockFactory = new MockFactory(MockBehavior.Loose);
}
[TearDown]
public void TearDown()
{
this.mockFactory.VerifyAll();
}
[Test]
[ExpectedException(typeof(NoBananasException))]
public void EatThrowsIfNoBananasAvailable
{
var bananaProvider = this.mockFactory.Create<IBananaProvider>();
bananaProvider.SetUp(bp => bp.IsBananaAvailable).Returns(false).Verifiable();
var monkey = new Monkey(bananaProvider.Object);
monkey.Eat();
}
Кажется, вы тестируете, что инъецированный экземпляр mockTcpClient удаляется, даже если конструктор генерирует исключение, и в этом случае это должно работать:
mockTcpClient.Setup(x => x.Dispose());
try
{
var popClient= new PopClient(null, mockTcpClient.Object);
}
finally
{
mockTcpClient.VerifyAll();
}
РЕДАКТИРОВАТЬ: Вообще-то, попробуйте/наконец-то станет чище, чем поймать Исключение. Обратите внимание, что вам не нужно удалять popClient, поскольку не создается экземпляр.