【问题标题】:Unit Test a Catch Block对 Catch 块进行单元测试
【发布时间】:2020-06-08 02:46:04
【问题描述】:

如何对下面的 catch 块进行单元测试?

下面是我的控制器定义:

public class RunController : Controller
{ 
    Public ActionResult GetExtraRun() 
    { 
        try{ 
             return View("ExtraRun"); 
        } catch(Exception ex) 
        { 
             _log.Error("Index -" + ex.Message, ex); 
             TempData[ErrorInfo] = GetErrorInfo(ex, "RunStatus"); 
             return RedirectToAction("Index", "RunErrorHandling"); 
        } 
     } 
} 

我正在使用最新的带有 Asp.NET Core MVC 3.0 版本的 NUnit 和 Moq。

所以我将有如下两个测试用例

  1. ) 检查是否返回查看成功。
  2. ) 我需要检查 catch 块作为代码覆盖的一部分。

所以我在上面给出的代码的第二点需要帮助。

【问题讨论】:

  • 根据你运行的单元测试,你会期待不同的结果,这取决于它是否是一个catch。然后你可以测试,例如调用工作的方法和调用引发异常的方法。如果返回的数据,例如包含在 catch 上返回的操作结果,并且您希望去那里,那么它会没问题。但无论如何,为了更好地测试,你应该看看依赖注入和模拟:stackoverflow.com/questions/2665812/what-is-mocking
  • 作为代码覆盖率部分,我需要这样做。从这个意义上说,你能帮忙吗?

标签: c# unit-testing asp.net-core-mvc nunit


【解决方案1】:

为了测试所需的代码块,您需要让控制器在

时抛出异常
return View("ExtraRun"); 

被调用。

这可以通过模拟控制器并覆盖View(string) 函数来完成,即virtual

[Microsoft.AspNetCore.Mvc.NonAction]
public virtual Microsoft.AspNetCore.Mvc.ViewResult View (string viewName);

以下示例使用 MOQ 来模拟控制器并覆盖预期的功能,以便在执行测试时控制器的行为符合预期。

//Arrange
//...
var mock = new Mock<RunController>({inject dependencies here});
mock.CallBase = true;

var exception = new Exception("Sample message");

mock.Setup(_ => _.View(It.IsAny<string>())).Throws(exception);

RunController controller = mock.Object;

//Act
var actual = controller.GetExtraRun() as RedirectToActionResult;

//Assert
actual.Should().NotBeNull(); //FluentAssertions

//...perform desired assertions here

通常在单元测试时不会模拟被测主题。然而,这种情况需要调用主题内的成员,该成员需要配置为按需要运行。这可以通过在派生类中覆盖它来完成。在没有模拟框架的情况下也可以手动完成相同的操作,但该框架简化了设置。

【讨论】:

    猜你喜欢
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多