我的私人方法中的代码行永远不会被覆盖

时间:2014-04-23 11:59:13

标签: c# unit-testing asp.net-mvc-4 moq private-members

下面是一段行动方法:

private static IEnumerable<SelectListItem> GetProductTypes()
{
    System.Text.RegularExpressions.Regex filter = new System.Text.RegularExpressions.Regex("Prodcut1|Prodcut2|Prodcut3");
    var prodtypes = from ProdType e in Enum.GetValues(typeof(ProdType))
                    where filter.IsMatch(e.ToString())
                    select new { Id = (int)e, Name = e.ToString() };

    if (prodtypes  != null)
    {
        return prodtypes .Select(x => new SelectListItem
               {
                   Value = x.Id.ToString(),
                   Text = x.Name
               });
    }
    return new List<SelectListItem>();
}

其中:ProdType是enum.And包含一些产品类型及其值。

我已经为该方法编写了单元测试: -

[TestMethod]
public void GetProductTypes_Test()
{
    //Arrange        
    PrivateType pvtType = new PrivateType(typeof(ProductController));
    //Act
    var actual = (IEnumerable<SelectListItem>)pvtType.InvokeStatic("GetProductTypes");

    //Assert
    Assert.IsNotNull(actual);
    Assert.IsInstanceOfType(actual, typeof(IEnumerable<SelectListItem>));
    Assert.AreEqual(3, actual.ToList().Count); //here : 3 = Product1,Product2,Product3
}

但是当我通过代码覆盖率选项检查其代码覆盖率时,它不会覆盖下面的代码行: -

return new List<SelectListItem>();

任何人都可以告诉我这里我做错了什么吗?是的,它是我正在测试的私有方法。因为我想测试所有私有方法。

1 个答案:

答案 0 :(得分:0)

Patryk已经说过:prodtypes永远不会是null 要获得100%的覆盖率,您可以将方法调整为以下之一(仅第二部分 - 第一部分保持不变):

private static IEnumerable<SelectListItem> GetProductTypes()
{
    //select prodtypes
    if (prodtypes != null && prodtypes.Count() > 0)
    {
        return prodtypes.Select(x => new SelectListItem
               {
                    Value = x.Id.ToString(),
                    Text = x.Name
               });
    }
    return new List<SelectListItem>();
}

或更短且更高效的,因为它永远不应该是null

private static IEnumerable<SelectListItem> GetProductTypes()
{
    //select prodtypes
    return prodtypes.Select(x => new SelectListItem
       {
            Value = x.Id.ToString(),
            Text = x.Name
       });
}

<强> BUT
正如约翰所提到的:在大多数情况下,你不应该对私有方法进行单元测试,因为它们应该由一些公共接口/方法覆盖。如果它没有被覆盖,想想这个方法 - 也许它根本不需要 - 已经发生在我身上几次了 但我还添加了“大多数情况下”,因为有些情况下测试私有方法是有意义的。在我的情况下,我有一些我的HW的错误处理方法,在正常的单元测试期间没有附加,因此我直接调用“私有错误处理程序”来检查它是否正常运行。但是你的方法看起来不像这样......

<强>更新
正如Episodex所建议的那样,该方法有更好的解决方案:

private static IEnumerable<SelectListItem> GetProductTypes()
{
    var filter = new System.Text.RegularExpressions.Regex("Prodcut1|Prodcut2|Prodcut3");
    return from ProdType e in Enum.GetValues(typeof(ProdType))
           where filter.IsMatch(e.ToString())
           select new SelectListItem 
               {
                   Value = ((int)e).ToString(), 
                   Text = e.ToString() 
                };
}