单元测试意外异常?

时间:2011-10-25 18:05:53

标签: c# asp.net-mvc model-view-controller unit-testing

是否可以对意外异常进行模拟或单元测试?代码覆盖率抱怨没有测试捕获,但你如何测试它?

    public List<Blog> SelectActiveBlogs()
    {
        List<Blog> returnCode = null;

        try
        {
            returnCode = GetQueryable<Blog>().Where(b => b.IsActive).ToList();
        }
        catch (Exception ex)
        {
            ExceptionHandler.HandleException(ex);
        }

        return returnCode;
    }

编辑: GetQueryable是一个使用存储库工厂获取db结果的方法,因此可能会有异常从生产中的db交互中冒出来,所以我想确保抓住它们如果出现问题,因此存在阻塞块。

EDIT2:该异常实际上由自定义类处理以保留堆栈跟踪,一旦记录它就不会被抛出。问题仍然是我是否可以在这种情况下嘲笑和抛出异常。

4 个答案:

答案 0 :(得分:1)

我认为你没有测试它。

我之前为测试系统无法达到的情况留下了许多异常处理程序。

在这种特殊情况下,您应该删除try / catch / throw,因为无论如何这都是无意义的代码。

答案 1 :(得分:1)

你可以使用ExpectedException属性来处理它,即使它没有被发现。它取决于您传递给参数的typeof参数。

[TestMethod]
[ExpectedException(typeof(Exception),
"A exception has been throws.")]
public List<Blog> SelectActiveBlogs()
{
    List<Blog> returnCode = null;

    try
    {
        returnCode = GetQueryable<Blog>().Where(b => b.IsActive).ToList();
    }
    catch (Exception ex)
    {
        throw ex;
    }

    return returnCode;
}

另一件事,如果你以这种方式实现它,你不需要try catch块。如果您捕获异常并且只重新抛出它(没有任何其他异常处理),那就毫无意义了。

希望有所帮助,如果没有请发表评论。祝你有愉快的一天!

答案 2 :(得分:1)

不要模拟方法GetQueryable(),而是负责获取可查询的类。

我猜你在GetQueryable()

中有一些像这样的代码
private IQueryable<T> GetQueryable<T>()
{
     return repository.query...
}

因此,不要尝试模拟方法,而是尝试使用存储库实例,并在调用查询时在模拟中抛出异常。

使用MoQ进行模拟不应该是复杂的 - 比如

var mock = new Moq.Mock<IRepository<Blog>>();
mock.Setup(r => r.Query()).Throws(new Exception("I'm really unexpected"));

我怀疑这项测试是否会带来更高的代码质量或更少的错误。但上述方法将取悦覆盖率工具;)

答案 3 :(得分:0)

如果您想进入exception,可以模拟调用GetQueryable<Blog>()并返回NULL,这会使代码抛出exception。或者你可以在模拟该调用时抛出异常,取决于你如何实现mock。 顺便说一句,如果你throw ex,你将丢失该代码中的堆栈跟踪。