gpt4 book ai didi

asp.net-mvc - 如何对 Controller 方法的 HandleError 属性的行为进行单元测试?

转载 作者:行者123 更新时间:2023-12-04 11:46:13 24 4
gpt4 key购买 nike

当发生意外错误时,我正在尝试验证我的 ASP.Net MVC 应用程序的行为。具体来说,我试图验证用户是否被定向到我为我的应用程序定义的错误页面。我遇到的问题是我无法按预期验证 Controller 方法的行为。

对于我的正常行为测试,我创建了一个模拟业务规则对象并将其传递给我的 Controller ,然后验证来自我想要测试的 Controller 方法的 ViewResult。当事情按预期工作时,这对我的目的很有效。 然而 ,当我从业务规则方法抛出异常时,异常通过 Controller 方法结果进行,而不是由 Controller 处理( Controller 方法具有 'HandleError' 属性),以便为我的错误页面提供适当的 ViewResult回来。

有没有办法以这种方式验证 HandleError 属性的行为?还是我完全错了?我意识到我可以使用 Selenium(会影响实际服务器的浏览器内测试)来验证实际浏览器中的行为,但是模拟这些测试可以让我更快地完成这项工作,并且开销更少......

示例测试代码:

// WidgetController.Index() makes a call to GetWidgets to retrieve a 
// List<Widget> instance.

// this works as expected since the appropriate ViewResult is returned
// by the controller
public void TestWidgetControllerIndex_NoResultsFound()
{
var mockBR = new Mock<IBusinessRules> { CallBase = true };
mockBR.Setup(br=>fr.GetWidgets()).Returns(new List<Widget>());
WidgetController controller = new WidgetController(mockBR.Object);
ViewResult result = (ViewResult)controller.Index();
Assert.AreEqual("Index", result.ViewName);
Assert.AreEqual(0,
((WidgetIndexViewData)result.ViewData.Model).Widgets.Count);
}

// this test is unable to reach the assertion statements due to the problem
// outlined above. WidgetController.Index has the HandleError attribute
// properly applied and the behaviour via the interface is as expected
public void TestWidgetControllerIndex_BusinessRulesExceptionEncountered()
{
var mockBR = new Mock<IBusinessRules> { CallBase = true };
mockBR.Setup(br=>fr.GetWidgets()).Throws<ApplicationException>();
WidgetController controller = new WidgetController(mockBR.Object);
ViewResult result = (ViewResult)controller.Index();
// The ApplicationException thrown by the business rules object bubbles
// up to the test through the line above. I was expecting this to be
// caught and handled by the HandleError filter (which would then let
// me verify the behaviour results via the assertion below)..
Assert.AreEqual("Error", result.ViewName);
}

我很感激任何关于我可能做错了什么的建议,或者我是否只是从完全错误的方向接近这个问题。我假设在 Controller 方法级别进行测试是合适的方法,因为那是应用 HandleError 属性的地方..(如果我确实需要在应用程序级别进行测试,是否可以通过类似实例化对象而不是使用 Selenium 之类的东西?)

更新
我得出的结论是,我不应该在每个 Controller 操作上测试与 HandleError 属性相关的功能。我实际上并不关心它的作用,我只是想确保错误得到处理(从我的测试角度来看,它的自定义代码或 MVC 库是否没有区别,这是我想要验证的功能)。

我最终做的是将我的 Controller 操作包装在 try/catch 块中,以便强制错误 View 作为方法的结果返回(而不是 ErrorHandler 属性在它离开方法时捕获错误)。这样我就可以在我的单元测试中断言错误得到了适当的反馈。我对这给我的 Controller 方法增加的额外长度不太满意,但它确实让我向用户提供了友好的、特定的错误消息(我正在使用扩展方法来显示反馈并执行日志记录)。 (因此,try/catch 方法肯定有利有弊。)

我不是 100% 肯定这是最干净的方法,但它实现了我的目标,即能够验证错误是通过 Controller 单元测试处理的(快速),而不必在浏览器中执行测试(慢) .所以基本上它现在已经足够了,直到我找到一个更干净的解决方案。如果有人遇到类似的问题并找到了更好的解决方案,我决定提供赏金。

最佳答案

我认为你不能对此进行单元测试。你也不想。您可以测试 Controller 方法是否抛出了预期的异常。使用反射,您可以测试操作或 Controller 是否具有您期望的属性以及该属性是否具有某些期望的属性值。但是,拦截异常并执行属性的工作是框架的行为,而不是您的代码。一般来说,您不应该测试不属于您的代码(框架)。

关于asp.net-mvc - 如何对 Controller 方法的 HandleError 属性的行为进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/778772/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com