在重组我的单元测试时,我目前正在寻找实现这一目标的不同可能性:
[TestClass]
public class CustomerTests : SuperTestBaseClass {
public CustomerTests() : base() { }
[TestMethod]
public void NameThrowsWhenNull() {
Throws<ArgumentNullException>(customer.Name = null);
}
}
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...
由于目标是使这种方法成为促进代码重用的最通用方法。
可行吗?如果是,那怎么办?
答案 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表达式替换为委托实例。