简体   繁体   English

单元测试异常属性

[英]Unit testing exception property

I have exception 我有例外

class SyntaxError : Exception {
    public SyntaxError(int l) {
        line = l;
    }
    public int line;
}

I'm using unit tests to test class Parser which on specific input should throw exception above. 我正在使用单元测试来测试类Parser,在特定输入上应该抛出异常。 I'm using code like this: 我正在使用这样的代码:

    [TestMethod]
    [ExpectedException(typeof(Parser.SyntaxError))]
    public void eolSyntaxError()
    {
        parser.reader = new StringReader("; alfa\n; beta\n\n\n\na");
        parser.eol();
    }

Is there any smart simple way to check if SyntaxError.line == 1 ? 是否有任何智能简单的方法来检查SyntaxError.line == 1

Best I come up with is: 我想出的最好的是:

    [TestMethod]
    public void eolSyntaxError()
    {
        try {
            parser.reader = new StringReader("; alfa\n; beta\n\n\n\na");
            parser.eol();
            Assert.Fail();
        } catch (SyntaxError e) {
            Assert.AreEqual(1, e.line);
        }
    }

I don't like it very much, is there better way? 我不太喜欢它,有更好的方法吗?

Consider using FluentAssertions . 考虑使用FluentAssertions Your test will then look like this: 您的测试将如下所示:

[TestMethod]
public void eolSyntaxError()
{
    parser.reader = new StringReader("; alfa\n; beta\n\n\n\na");

    Action parseEol = () => parser.eol();

    parseEol
        .ShouldThrow<SyntaxError>()
        .And.line.Should().Be(1);
}

Otherwise, your approach is pretty much as good as it gets. 否则,你的方法几乎和它一样好。

You could write a method similar to the one in NUnit 您可以编写类似于NUnit中的方法

public T Throws<T>(Action code) where T : Exception
{
    Exception coughtException = null;
    try
    {
        code();
    }
    catch (Exception ex)
    {
        coughtException = ex;
    }

    Assert.IsNotNull(coughtException, "Test code didn't throw exception");
    Assert.AreEqual(coughtException.GetType(), typeof(T), "Test code didn't throw same type exception");

    return (T)coughtException;
}

And then you can use it in your test method 然后你可以在你的测试方法中使用它

Parser.SyntaxError exception = Throws<Parser.SyntaxError>(() => parser.eol());
Assert.AreEqual(1, exception.line);

As per my comment, if the line at which you encounter the syntax error is relevant, then include it in your custom exception class, like so. 根据我的评论,如果您遇到语法错误的行是相关的,那么将它包含在您的自定义异常类中,就像这样。

public class SyntaxError : Exception
{
     public SyntaxError(int atLine)
     {
         AtLine = atLine;
     }

     public int AtLine { get; private set; }
}

Then it's easy to test. 然后它很容易测试。

EDIT - After having read the question (!) here's a simple additional Assert method which will tidy up your exception assertions. 编辑 - 在阅读了问题(!)后,这是一个简单的附加Assert方法,它将整理你的异常断言。

public static class xAssert
{
    public static TException Throws<TException>(Action a) where TException : Exception
    {
        try
        {
            a();
        }
        catch (Exception ex)
        {
            var throws = ex as TException;
            if (throws != null)
                return throws;
        }
        Assert.Fail();
        return default(TException);
    }
}

Usage as follows... 用法如下......

public class Subject
{
    public void ThrowMyException(int someState)
    {
        throw new MyException(someState);
    }

    public void ThrowSomeOtherException()
    {
        throw new InvalidOperationException();
    }
}

public class MyException : Exception
{
    public int SomeState { get; private set; }

    public MyException(int someState)
    {
        SomeState = someState;
    }
}

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var subject = new Subject();
        var exceptionThrown = xAssert.Throws<MyException>(() => { subject.ThrowMyException(123); });

        Assert.AreEqual(123, exceptionThrown.SomeState);
    }
}

I am not aware of an out of the box solution for this, but I have seen the concept of expectations which work like this: 我不知道为此提供开箱即用的解决方案,但我已经看到了期望的概念,它的工作原理如下:

[TestMethod]
public void EolSyntaxError()
{
    Expectations.Expect<(SyntaxError>(
        () =>
        {
            parser.reader = new StringReader("; alfa\n; beta\n\n\n\na");
            parser.eol();
        },
        e =>
        {
            Assert.AreEqual(1, e.line);
        });
}

Expectations needs to be implemented. 期望需要实施。 I reckon there will be libraries out there which already do this. 我估计那里会有图书馆已经做到了这一点。 Anyhow, the Expect method in Expectations could look like this: 无论如何, ExpectationsExpect方法看起来像这样:

public static void Expect<TExpectedException>(
    System.Action action,
    System.Action<TExpectedException> assertion) where TExpectedException : Exception
{
    if (action == null) { throw new ArgumentNullException("action"); }
    try
    {
        action.Invoke();
        Assert.Fail(string.Format("{0} expected to be thrown", typeof(TExpectedException).Name));
    }
    catch (TExpectedException e)
    {
        assertion.Invoke(e);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM