Перехват типов исключений, заданных в качестве параметров типа в C # 2.0 - PullRequest
2 голосов
/ 18 ноября 2009

В следующем методе первый блок catch никогда не запускается, даже если выдается исключение типа ExceptionType:

    /// <summary>
    /// asserts that running the command given throws an exception.
    /// </summary>
    public static void Throws<ExceptionType>(ICommand cmd)
        where ExceptionType : Exception
    {
        // Strangely, using 2 catch blocks on the code below makes the first catch block do nothing.
        try
        {
            try
            {
                cmd.Execute();
            }
            catch (ExceptionType)
            {
                return;
            }
        }
        catch (Exception f)
        {
            throw new AssertionException(cmd.ToString() + " threw an exception of type " + f.GetType() + ".  Expected type was " + typeof(ExceptionType).Name + ".");
        }

        throw new AssertionException(cmd.ToString() + " failed to throw a " + typeof(ExceptionType).Name + ".");
    }

как указано в следующем тесте:

    [Test]
    public void Test_Throws_CatchesSpecifiedException()
    {
        AssertThat.Throws<AssertionException>(
            new FailureCommand()
        );
    }

используя следующий класс:

class FailureCommand : ICommand
{
    public object Execute()
    {
        Assert.Fail();
        return null;    // never reached.
    }

    public override string ToString()
    {
        return "FailureCommand";
    }
}

дает следующий вывод в NUnit:

TestUtil.Tests.AssertThatTests.Test_Throws_CatchesSpecifiedException: FailureCommand выдал исключение типа NUnit.Framework.AssertionException. Ожидаемый тип: AssertionException.

Я также пытался использовать 2 блока catch для 1 блока try (вместо того, чтобы вкладывать try / catch во внешнюю попытку), но получил те же результаты.

Есть идеи, как перехватить исключение, указанное в качестве параметра типа в одном блоке перехвата, но перехватить все другие исключения в другом?

Ответы [ 3 ]

3 голосов
/ 18 ноября 2009

отлично работает для меня в этом тесте:

using System;
using System.IO;

class Test
{
    static void Main()
    {
        Throws<ArgumentNullException>(() => File.OpenText(null));
    }

    public static void Throws<ExceptionType>(Action cmd)
        where ExceptionType : Exception
    {
        try
        {
            try
            {
                cmd();
            }
            catch (ExceptionType)
            {
                Console.WriteLine("Caught!");
                return;
            }
        }
        catch (Exception f)
        {
            Console.WriteLine("Threw an exception of type " + f.GetType() 
                + ".  Expected type was " + typeof(ExceptionType) + ".");
        }

        Console.WriteLine("No exception thrown");
    }
}

Насколько вы уверены, что два AssertionException исключения идентичны? Они определенно находятся в одном и том же пространстве имен (напечатайте typeof(ExceptionType), а не только свойство Name)? Они из одной сборки? Я не удивлюсь, обнаружив некоторые странности из-за сосуществования нескольких версий инфраструктуры тестирования ...

Попробуйте сделать исключение, отличное от AssertionException, чтобы упростить жизнь.

1 голос
/ 18 ноября 2009

См. Эту тему для получения дополнительной информации: Почему я не могу поймать универсальное исключение в C #?

Кажется, это ошибка: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=362422&wa=wsignin1.0

0 голосов
/ 18 ноября 2009

Я не отлаживал этот код и не смотрел на него слишком долго, но может случиться так, что вы в результате первого «возврата» вызываете код для HALT и покидаете метод. Таким образом, исключение «перехватывается» или «обрабатывается» (как бы вы на него ни смотрели), а внешний блок try / catch никогда не выполняется.

Вы пытаетесь это сделать?

try        
{            
    try            
    {                
        cmd.Execute();            
    }            
    catch (ExceptionType)            
    {                
        throw;
    }        
}        
catch (Exception f)        
{            
    throw new AssertionException(cmd.ToString() + " threw an exception of type " + f.GetType() + ".  Expected type was "  + typeof(ExceptionType).Name + ".");        
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...