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

发布于 2024-10-22 07:11:35 字数 2427 浏览 2 评论 0原文

这是我的测试:

[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 =>; “页”+1;

而不是

Func pageUrl = i => “页”+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 页这一事实引起的。

这个计算有问题吗?

Here is my test:

[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>");
    }
}

Here is the PageLinks extension method:

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());
}

Finally here is the result for the running test:

SportsStore.UnitTests.DisplayingPageLinks.Can_Generate_Links_To_Other_Pages:
Expected string length 63 but was 59.
Strings differ at index 24.
Expected: "123" But was: "12"
-----------------------------------^

The error doesn't copy the way it's shown in the GUI - sorry.

Can you give me some suggestions as to why NUnit is saying it receives something I don't expect it to give out.

According to what I'm reading in the PageLinks extension method, it seems that the markup should be formed correctly.

Any suggestions? I'm a TDD newbie and really trying to learn here. :)


Edit:

It seems the culprit was this. My Test was using:
Func pageUrl = i => "Page" + 1;

instead of

Func pageUrl = i => "Page" + i;

But now there's another error. :(

It seems something is wrong when calculating the amount of pages in the PagingInfo class:

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); }
    }
}

It seems the error stems on the fact that this is returning 2 pages, instead of 3.

Is there something wrong in this calculation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

紫轩蝶泪 2024-10-29 07:11:35

(回复您编辑中提出的新问题。)PageLinks() 中的循环以 i = 1 开始,并且 i i i i i i i i i i i pagingInfo.TotalPages 作为条件 - 典型的相差一错误。 :-)

(Replying to the new question posed in your edit.) Your loop in PageLinks() is starting with i = 1 and having i < pagingInfo.TotalPages as condition - a classical off-by-one error. :-)

少女的英雄梦 2024-10-29 07:11:35

这个计算有问题吗?

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

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

如果这些单元测试表明该函数正在正确计算您的输入,那么您就知道消费类一定提供了错误的输入。

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

Is there something wrong in this calculation?

Good question. As an exercise in proper Test-Driven Design, try creating a unit test that isolates this specific calculation. Something like this:

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

If these unit tests show that the function is calculating your input correctly, then you know that the consuming class must be providing the wrong inputs.

The real issue here is probably the one that Aasmund found, but I hope this answer gives you an idea about how to improve your unit testing to hone in on the real source of errors.

江南月 2024-10-29 07:11:35

这个计算有问题吗?

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

是的,您对所涉及的类型和操作的态度是反复无常的。如果不知道运算符优先级,您不知道小数转换是否在除法之前应用,因此不知道除法是小数除法还是整数除法。

使用多个语句并明确类型。阅读这个发布


我会将否决票视为寻求更多帮助的提示。考虑一下:输入都是整数。这个问题可以在整数域中解决吗?有必要涉及小数吗?


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

Is there something wrong in this calculation?

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

Yes, you are playing fast and loose with the types and operations involved. Without knowing operator precedence, you don't know if the decimal convert is applied before the divide, and therefore don't know if the divide is a decimal divide or an int divide.

Use multiple statements and be clear with the types. Read this post.


I will consider the downvote as a prompt for more help. Consider this: the inputs are all integers. Can the problem be resolved in the domain of integers? Is it necessary to involve decimals at all?


public int GetTotalPages()
{
  int fullPages = TotalItems / ItemsPerPage;
  bool partialPage = TotalItems % ItemsPerPage != 0;
  int result = fullPages + (partialPage ? 1 : 0);
  return result;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文