首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ASP.NET MVC -单元测试过度杀伤力?(TDD)

ASP.NET MVC -单元测试过度杀伤力?(TDD)
EN

Stack Overflow用户
提问于 2009-09-03 06:47:40
回答 5查看 1.4K关注 0票数 17

所以我开始发现TDD的bug,但我想知道我是否真的做对了……我似乎正在写很多的测试。

当然,测试越多越好,但我有一种感觉,我已经结束了。老实说,我不知道我还能继续写这些简单的重复测试多久。

例如,以下是来自my AccountController的LogOn操作:

代码语言:javascript
复制
public ActionResult LogOn(string returnUrl)
{
    if (string.IsNullOrEmpty(returnUrl))
        returnUrl = "/";

    var viewModel = new LogOnForm()
    {
        ReturnUrl = returnUrl
    };

    return View("LogOn", viewModel);
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOn(LogOnForm logOnForm)
{
    try
    {
        if (ModelState.IsValid)
        {
            AccountService.LogOnValidate(logOnForm);

            FormsAuth.SignIn(logOnForm.Email, logOnForm.RememberMe);

            return Redirect(logOnForm.ReturnUrl);
        }
    }
    catch (DomainServiceException ex)
    {
        ex.BindToModelState(ModelState);
    }
    catch
    {
        ModelState.AddModelError("*", "There was server error trying to log on, try again. If your problem persists, please contact us.");
    }

    return View("LogOn", logOnForm);
}

非常不言自明。

然后,我有了下面的测试套件

代码语言:javascript
复制
public void LogOn_Default_ReturnsLogOnView()
public void LogOn_Default_SetsViewDataModel()
public void LogOn_ReturnUrlPassedIn_ViewDataReturnUrlSet()
public void LogOn_ReturnUrlNotPassedIn_ViewDataReturnUrDefaults()
public void LogOnPost_InvalidBinding_ReturnsLogOnViewWithInvalidModelState()
public void LogOnPost_InvalidBinding_DoesntCallAccountServiceLogOnValidate()
public void LogOnPost_ValidBinding_CallsAccountServiceLogOnValidate()
public void LogOnPost_ValidBindingButAccountServiceThrows_ReturnsLogOnViewWithInvalidModelState()
public void LogOnPost_ValidBindingButAccountServiceThrows_DoesntCallFormsAuthServiceSignIn()
public void LogOnPost_ValidBindingAndValidModelButFormsAuthThrows_ReturnsLogOnViewWithInvalidModelState()
public void LogOnPost_ValidBindingAndValidModel_CallsFormsAuthServiceSignIn()
public void LogOnPost_ValidBindingAndValidModel_RedirectsToReturnUrl()

是不是杀过头了?我甚至还没有展示服务测试!

我可以剔除哪些(如果有的话)?

蒂娅

查尔斯

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-09-03 07:10:23

这完全取决于你需要/想要多少覆盖率,以及有多大的可靠性是一个问题。

这里是你应该问自己的问题:

  • Does此单元测试帮助实现我还没有have?
  • Will的功能/代码更改此单元测试帮助回归测试/调试此单元如果我对代码进行更改以满足此单元测试的重要性,或者它是否值得单元test?

关于第三个,我记得当我开始写单元测试的时候(我知道,和TDD不是一回事),我会有这样的测试:

代码语言:javascript
复制
string expected, actual;
TypeUnderTest target = new TypeUnderTest();
target.PropertyToTest = expected;
actual = target.PropertyToTest;
Assert.AreEqual<string>(expected, actual);

我本可以用我的时间做一些更有效率的事情,比如为我的桌面选择一张更好的墙纸。

我推荐这篇由ASP.net MVC书籍作者桑德森撰写的文章:

http://blog.codeville.net/2009/08/24/writing-great-unit-tests-best-and-worst-practises/

票数 17
EN

Stack Overflow用户

发布于 2009-09-03 07:09:33

我会说你做的比你可能必须做的要多一点。虽然测试代码可以采用的每一条可能的路径是很好的,但有些路径并不是很重要,或者不会导致行为上的真正差异。

在您的示例中,以LogOn(string returnUrl)为例

您要做的第一件事是检查returnUrl参数,如果该参数为null/空,则将其重新赋值为默认值。您真的需要整个单元测试来确保一行代码按预期运行吗?这不是一条容易打破的线。

大多数可能会破坏这一行的更改都会抛出编译错误。可以在该行中更改指定的缺省值(也许您稍后会认为"/“不是一个好的缺省值...但是在你的单元测试中,我打赌你是硬编码来检查"/“的,不是吗?因此,值的更改将需要在测试中进行更改...这意味着你不是在测试你的行为,而是在测试你的数据。

只需进行一次不提供参数的测试,即可实现对该方法行为的测试。这将命中例程的"set default“部分,同时仍在测试其余代码是否运行良好。

票数 5
EN

Stack Overflow用户

发布于 2009-09-03 06:55:33

这在我看来是正确的。是的,您将编写大量的单元测试,并且,开始时,它看起来像是大材小用和浪费时间;但坚持下去,这是值得的。你的目标应该是(而不仅仅是100%的代码覆盖率)是100%的函数覆盖率。然而..。如果你发现你为同一个方法编写了很多it,那么这个方法可能做得太多了。试着更多地分离你的关注点。根据我的经验,Action的主体应该只是创建一个类来做真正的工作。这才是UTs真正应该针对的类。

克里斯

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1371755

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档