单元测试控制器中抛出的异常
我目前正在单元测试,发送无效表单集合数据时发生错误。单元测试控制器中抛出的异常
唯一的例外是HttpPost指数ActionResult的方法(如下所示)中抛出:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(FormCollection formCollection, PaymentType payType, string progCode)
{
ActionResult ar = redirectFromButtonData(formCollection, payType, progCode);
if (ar != null)
{
return ar;
}
else
{
throw new Exception("Cannot redirect to payment form from cohort decision - Type:[" + payType.ToString() + "] Prog:[" + Microsoft.Security.Application.Encoder.HtmlEncode(progCode) + "]");
}
}
到目前为止,我已经写了一个测试,成功击中异常(我已经启用代码覆盖率,我已经验证这一点正在使用,看看每个单独的测试正在执行什么代码),但目前测试失败,因为我还没有定义一种测试方法,已抛出异常,此测试的代码可以在下面找到:
[TestMethod]
public void Error_Is_Thrown_If_HVM_FormCollection_Data_Is_Incorrect()
{
var formCollection = new FormCollection();
formCollection.Add("__RequestVerificationToken", "__RequestVerificationToken");
formCollection.Add("invalid - invalid", "invalid- invalid");
var payType = new PaymentType();
payType = PaymentType.deposit;
var progCode = "hvm";
var mocks = new MockRepository();
var httpRequest = mocks.DynamicMock<HttpRequestBase>();
var httpContext = mocks.DynamicMock<HttpContextBase>();
controller.ControllerContext = new ControllerContext(httpContext, new RouteData(), controller);
mocks.ReplayAll();
httpRequest.Expect(r => r.Url).Return(new Uri("http://localhost:8080/hvm/full/self/")).Repeat.Any();
httpContext.Expect(c => c.Request).Return(httpRequest).Repeat.Any();
var result = controller.Index(formCollection, payType, progCode);
}
我看过使用[ExpectedException(typeof(Exception)]
注释可以在这种情况下使用?
我冒昧地改变你的测试代码,稍微符合rhino-mocks的最新功能。它不再需要创建MockRepository
,您可以使用静态类MockRepository
并致电GenerateMock<>
。我还将您的SuT(系统在测试中)实例化为以下的您的嘲笑规范。 (我对Nunit的使用经验比使用MSTest更好,主要是因为Nunit的发布频率更高,功能更可靠,再次,不确定它是否适用于TFS,但不应该很难找到)。
[Test] // Nunit
[ExpectedException(typeof(Exception)) // NOTE: it's wise to throw specific
// exceptions so that you prevent false-positives! (another "exception"
// might make the test pass while it's a completely different scenario)
public void Error_Is_Thrown_If_HVM_FormCollection_Data_Is_Incorrect()
{
var formCollection = new FormCollection();
formCollection.Add("__RequestVerificationToken", "__RequestVerificationToken");
formCollection.Add("invalid - invalid", "invalid- invalid");
var payType = new PaymentType();
payType = PaymentType.deposit;
var progCode = "hvm";
var httpRequest = MockRepository.GenerateMock<HttpRequestBase>();
var httpContext = MockRepository.GenerateMock<HttpContextBase>();
// define behaviour
httpRequest.Expect(r => r.Url).Return(new Uri("http://localhost:8080/hvm/full/self/")).Repeat.Any();
httpContext.Expect(c => c.Request).Return(httpRequest).Repeat.Any();
// instantiate SuT (system under test)
controller.ControllerContext = new ControllerContext(httpContext, new RouteData(), controller);
// Test the stuff, and if nothing is thrown then the test fails
var result = controller.Index(formCollection, payType, progCode);
}
和MStest几乎相同的处理,除了你需要定义预期的异常多一点oldskool。 Assert exception from NUnit to MS TEST:
[TestMethod] // MStest
public void Error_Is_Thrown_If_HVM_FormCollection_Data_Is_Incorrect()
{
try
{
var formCollection = new FormCollection();
formCollection.Add("__RequestVerificationToken", "__RequestVerificationToken");
formCollection.Add("invalid - invalid", "invalid- invalid");
var payType = new PaymentType();
payType = PaymentType.deposit;
var progCode = "hvm";
var httpRequest = MockRepository.GenerateMock<HttpRequestBase>();
var httpContext = MockRepository.GenerateMock<HttpContextBase>();
// define behaviour
httpRequest.Expect(r => r.Url).Return(new Uri("http://localhost:8080/hvm/full/self/")).Repeat.Any();
httpContext.Expect(c => c.Request).Return(httpRequest).Repeat.Any();
// instantiate SuT (system under test)
controller.ControllerContext = new ControllerContext(httpContext, new RouteData(), controller);
// Test the stuff, and if nothing is thrown then the test fails
var result = controller.Index(formCollection, payType, progCode);
}
catch (Exception)
{
Assert.Pass();
}
Assert.Fail("Expected exception Exception, was not thrown");
}
如果你有这部分的工作,你可以通过提供的链接重构它更好的可重用性。
对于'MsTest'测试,只有可能会在try块中抛出异常的调用可能会更清晰一些? – levelnis 2013-02-13 15:10:50
为项目的下一次迭代我将进行大量的重构,因此无论如何可能会考虑移动到NUnit,我打算对可能使用重定向处理错误的方式进行一些更改,以便它转发到自定义错误视图而不是抛出异常。我有另外两个基于MVC 4的项目,它使用这种方法,并且它更容易测试 – CryoFusion87 2013-02-13 15:21:32
对我来说,它表示没有用于** MSTest **的'Assert.Pass()'! – Ciwan 2017-03-02 10:41:02
测试这个最简单的方法是将调用包装在try-catch中并在catch块执行时设置布尔变量。例如:
var exceptionIsThrown = false;
ActionResult result;
try
{
result = controller.Index(formCollection, payType, progCode);
}
catch(Exception)
{
exceptionIsThrown = true;
}
heya,您使用的是哪种版本的鼻假手术? – bas 2013-02-13 14:43:27
其版本3.6.0.0 – CryoFusion87 2013-02-13 14:45:58
hmm,ExpectedException可能是MStest的错误。 Nunit支持它更好。有没有MStest的原因,或者你可以切换到Nunit没有问题? – bas 2013-02-13 14:46:18