使用Func <t,tresult =“”>或Action <t>来实现这一点是否可行?</t> </t,>

时间:2014-03-21 18:10:11

标签: c# delegates func

在重组我的单元测试时,我目前正在寻找实现这一目标的不同可能性:

CustomerTests

[TestClass]
public class CustomerTests : SuperTestBaseClass {
    public CustomerTests() : base() { }

    [TestMethod]
    public void NameThrowsWhenNull() { 
        Throws<ArgumentNullException>(customer.Name = null);
    }
}

SuperTestBaseClass

public abstract class SuperTestBaseClass {
    protected SuperTestBaseClass() { }

    public void Throws<TException>(Func<T, TResult> propertyOrMethod) {
        // arrange
        Type expected = typeof(TException);
        Exception actual = null;

        // act
        try { propertyOrMethod(); } catch (Exception ex) { actual = ex; }

        // assert
        Assert.IsInstanceOfType(actual, expected);
    }
}

propertyOrMethod中执行try/catch的地方,而不必编写类似的内容:

try { propertyOrMethod.Name = null } catch...

由于目标是使这种方法成为促进代码重用的最通用方法。

可行吗?如果是,那怎么办?

3 个答案:

答案 0 :(得分:3)

在您的方法上使用[ExpectedException(typeof(ArgumentNullException)],您将不需要任何自定义内容。

[TestClass]
public class CustomerTests : SuperTestBaseClass {
    public CustomerTests() : base() { }

    [TestMethod]
    [ExpectedException(typeof(ArgumentNullException)]
    public void NameThrowsWhenNull() { 
        customer.Name = null;
    }
}

答案 1 :(得分:2)

我愿意:

public TException Throws<TException>(Action act) where TException : Exception 
{
        // act
        try { act(); } catch (TException ex) { return ex; }

        // assert
        Assert.Fail("Expected exception");
        return default(TException);   //never reached
}

然后你可以做

Throws<ArgumentNullException>(() => { customer.Name = null; });

请注意,NUnit内置了此方法(Assert.Throws/Catch),因此如果您正在使用它,则不需要此功能。

答案 2 :(得分:1)

如果你使用NUnit,那么你可以这样做:

Assert.That(() => { ... }, Throws.InstanceOf<ArgumentException>()));

如果需要,可以将lambda表达式替换为委托实例。