В любом случае вызывается ожидание исключения в тесте, но желание проверить удаление - PullRequest
2 голосов
/ 24 октября 2009

Я тестирую демонстрационное приложение, которое является клиентом 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);

Но утилита не называется , похоже, это спецификация C #.

Ответы [ 4 ]

3 голосов
/ 24 октября 2009
mockTcpClient.Setup(x => x.Dispose());

try 
{
    using (var popClient = new PopClient(null, mockTcpClient.Object))
    {

    }
}
finally 
{
    mockTcpClient.VerifyAll();
}
2 голосов
/ 26 октября 2009

Это не отвечает на ваш вопрос (так как он уже решен), но он уместен и в любом случае стоит опубликовать.

[ExpectedException] - довольно сложный способ проверки исключений. Это может быть подвержено ошибкам, так как неправильная строка может вызвать исключение ожидаемого типа, что приведет к ошибочной передаче. Я настоятельно рекомендую вам проверить Assert.Throws () вместо:)

Это лучше использовать (вы можете запросить возвращенное исключение), более читабельно и, прежде всего, безопаснее.

Вы можете найти пример здесь

2 голосов
/ 25 октября 2009

Вы уже обнаружили, что dispose действительно не , который должен вызываться в случае сбоя конструктора. Но могут быть и другие случаи, когда вы захотите проверить свои ложные показания после того, как выдается ожидаемое исключение. Я просто делаю это в тесте 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();
}
1 голос
/ 24 октября 2009

Вы, похоже, проверяете, что внедренный экземпляр mockTcpClient удаляется, даже если конструктор выдает исключение, и в этом случае это должно работать:

mockTcpClient.Setup(x => x.Dispose());
try
{
    var popClient= new PopClient(null, mockTcpClient.Object);
}
finally
{
    mockTcpClient.VerifyAll();
}

РЕДАКТИРОВАТЬ: На самом деле, попытка / наконец будет чище, чем ловить исключение. Обратите внимание, что вам не нужно утилизировать popClient, поскольку экземпляр не создается.

...