单元测试表现得很奇怪 - 你能否解释一下这个谜团?

时间:2011-03-15 22:07:16

标签: c# unit-testing tdd nunit

这是我的测试:

[TestFixture]
public class DisplayingPageLinks
{
    [Test]
    public void Can_Generate_Links_To_Other_Pages()
    {
        //Arrange: We're going to extend the Html helper class.
        //It doesn't matter if the variable we use is null            
        HtmlHelper html = null;

        PagingInfo pagingInfo = new PagingInfo(){
            CurrentPage = 2,
            TotalItems = 28,
            ItemsPerPage = 10
        };

        Func<int, String> pageUrl = i => "Page" + 1;

        //Act: Here's how it should format the links.
        MvcHtmlString result = html.PageLinks(pagingInfo, pageUrl);

        //Assert:
        result.ToString().ShouldEqual(@"<a href=""Page1"">1</a><a href=""Page2"">2</a><a href=""Page3"">3</a>");
    }
}

以下是PageLinks扩展方法:

public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int,string> pageUrl)
{
    StringBuilder result = new StringBuilder();

    for (int i = 1; i < pagingInfo.TotalPages; i++)
    {
        TagBuilder tag = new TagBuilder("a");
        tag.MergeAttribute("href", pageUrl(i));
        tag.InnerHtml = i.ToString();
        if (i == pagingInfo.CurrentPage)
        {
            tag.AddCssClass("selected");
        }
        result.Append(tag.ToString());
    }

    return MvcHtmlString.Create(result.ToString());
}

最后,这是运行测试的结果:

  

SportsStore.UnitTests.DisplayingPageLinks.Can_Generate_Links_To_Other_Pages:   预计字符串长度为63但是为59。   字符串在索引24处不同。
  预计:“123”但是:“12”
  ----------------------------------- ^

错误不会复制GUI中显示的方式 - 抱歉。

你能否给我一些建议,说明为什么NUnit会说它收到了我不希望它发出的东西。

根据我在PageLinks扩展方法中读到的内容,似乎应该正确形成标记。

有什么建议吗?我是TDD新手,真的想在这里学习。 :)


修改

这似乎是罪魁祸首。我的测试使用:     Func pageUrl = i =&gt; “Page”+ 1;

而不是

Func pageUrl = i =&gt; “Page”+ i;

但现在又出现了另一个错误。 :(

在计算PagingInfo类中的页面数量时似乎有问题:

public class PagingInfo
{
    public int TotalItems { get; set; }
    public int ItemsPerPage { get; set; }
    public int CurrentPage { get; set; }

    public int TotalPages
    {
        get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); }
    }
}

似乎错误源于这个事实是返回2页,而不是3页。

这次计算有什么问题吗?

3 个答案:

答案 0 :(得分:4)

(回复编辑中提出的新问题。)PageLinks()中的循环以i = 1开头并以i < pagingInfo.TotalPages为条件 - 一个经典的逐个错误。 : - )

答案 1 :(得分:1)

  

这次计算有什么问题吗?

public int TotalPages
{
  get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); }
}

是的,您正在快速松散地参与所涉及的类型和操作。在不知道运算符优先级的情况下,您不知道在除法之前是否应用了十进制转换,因此不知道除数是小数除数还是除数。

使用多个语句并明确类型。阅读this post


我会将downvote视为提供更多帮助的提示。考虑一下:输入都是整数。可以在整数域中解决问题吗?是否有必要包含小数?


public int GetTotalPages()
{
  int fullPages = TotalItems / ItemsPerPage;
  bool partialPage = TotalItems % ItemsPerPage != 0;
  int result = fullPages + (partialPage ? 1 : 0);
  return result;
}

答案 2 :(得分:1)

  

这次计算有什么问题吗?

好问题。作为适当的测试驱动设计的练习,尝试创建一个单元测试,隔离这个特定的计算。像这样:

Assert.AreEqual(3, new PagingInfo {TotalItems = 4, ItemsPerPage = 9}.TotalPages);

如果这些单元测试显示函数正确计算输入,那么您就知道消费类必须提供错误的输入。

这里的真正问题可能是Aasmund发现的问题,但我希望这个答案可以帮助您了解如何改进单元测试以了解真正的错误来源。