gpt4 book ai didi

asp.net-mvc - 我只是不了解 TDD 单元测试(Asp.Net MVC 项目)吗?

转载 作者:行者123 更新时间:2023-12-03 12:03:22 25 4
gpt4 key购买 nike

我想弄清楚如何正确有效地对我的 Asp.net MVC 项目进行单元测试。当我开始这个项目时,我购买了 Pro ASP.Net MVC,通过这本书我了解了 TDD 和单元测试。在看到这些示例之后,以及我在目前的公司担任 QA 软件工程师这一事实后,我对 TDD 的强大功能感到惊讶。所以我开始着手我的项目,并开始为我的数据库层、业务层和 Controller 编写单元测试。一切都在实现之前进行了单元测试。起初我认为这很棒,但后来事情开始走下坡路。

以下是我开始遇到的问题:

  • 我最终编写了应用程序代码,以便能够执行单元测试。我的意思不是很好,因为我的代码被破坏了,我不得不修复它以便单元测试通过。我的意思是,由于使用 linq 进行数据检索(使用通用存储库模式),将数据库抽象为模拟数据库是不可能的。

    原因是使用 linq->sql 或 linq->entities 您可以通过执行以下操作进行连接:
    var objs = select p from _container.Projects select p.Objects;

    但是,如果您模拟数据库层,为了让 linq 通过单元测试,您必须将 linq 更改为
    var objs = select p from _container.Projects
    join o in _container.Objects on o.ProjectId equals p.Id
    select o;

    这不仅意味着您正在更改您的应用程序逻辑,以便您可以对其进行单元测试,而且您只是为了可测试性而降低了代码的效率,并且首先摆脱了使用 ORM 的许多优势.

    此外,由于我的模型的很多 ID 都是数据库生成的,我证明必须编写额外的代码来处理非数据库测试,因为 ID 从未生成过,而且我仍然必须处理这些情况才能通过单元测试,但它们永远不会发生在真实场景中。

    因此,我最终放弃了我的数据库单元测试。
  • 只要我返回 View ,为 Controller 编写单元测试就很容易。但是,我的应用程序的主要部分(以及最能从单元测试中受益的部分)是一个复杂的 ajax Web 应用程序。出于各种原因,我决定将应用程序从返回 View 更改为使用我需要的数据返回 JSON。发生这种情况后,我的单元测试变得非常难以编写,因为我还没有找到任何为非平凡的 json 编写单元测试的好方法。

    在绞尽脑汁并浪费了大量时间试图找到一种对 JSON 进行单元测试的好方法之后,我放弃并删除了所有 Controller 单元测试(到目前为止,所有 Controller 操作都集中在应用程序的这一部分)。
  • 所以最后我只剩下测试服务层 (BLL) 了。现在我正在使用 EF4,但是我在 linq->sql 中也遇到了这个问题。我选择了 EF4 模型优先的方法,因为对我来说,这样做是有意义的(定义我的业务对象并让框架弄清楚如何将它转换到 sql 后端)。一开始这很好,但现在由于关系而变得很麻烦。

    例如说我有 Project , User , 和 Object实体。一个对象必须与一个项目相关联,一个项目必须与一个用户相关联。这不仅是特定于数据库的规则,也是我的业务规则。但是,假设我想做一个能够保存对象的单元测试(举个简单的例子)。我现在必须执行以下代码以确保保存有效:
    User usr = new User { Name = "Me" };
    _userService.SaveUser(usr);

    Project prj = new Project { Name = "Test Project", Owner = usr };
    _projectService.SaveProject(prj);

    Object obj = new Object { Name = "Test Object" };
    _objectService.SaveObject(obj);

    // Perform verifications

    仅仅为了执行一个单元测试而必须完成所有这些有很多问题。这有几个问题。
  • 对于初学者来说,如果我添加一个新的依赖项,例如所有项目都必须属于一个类别,我必须进入每个引用项目的单元测试,添加代码以保存类别,然后添加代码以将类别添加到项目中。对于非常简单的业务逻辑更改而言,这可能是一项巨大的努力,但我将为此需求修改的单元测试几乎没有一个实际上是为了测试该功能/需求。
  • 如果我随后向我的 SaveProject 方法添加验证,以便项目不能被保存,除非它们的名称至少包含 5 个字符,然后我必须通过每个对象和项目单元测试以确保新的需求不会产生任何不相关的单元测试都失败了。
  • 如果在 UserService.SaveUser() 中有问题方法它会导致所有项目和对象单元测试失败,并且原因不会立即引起注意,而不必深入研究异常。

  • 因此,我从我的项目中删除了所有服务层单元测试。

    我可以继续下去,但到目前为止,我还没有看到任何单元测试可以真正帮助我而不妨碍我的方法。我可以看到我可以并且可能会实现单元测试的特定情况,例如确保我的数据验证方法正常工作,但这些情况很少见。我的一些问题可能可以得到缓解,但不能不为我的应用程序添加额外的层,从而产生更多的故障点,以便我可以进行单元测试。

    因此,我的代码中没有单元测试。幸运的是,我大量使用源代码控制,因此如果需要,我可以将它们取回,但我只是不明白这一点。

    我在互联网上到处都看到人们在谈论 TDD 单元测试有多棒,而我不仅仅是在谈论狂热的人。少数不理会 TDD/单元测试的人提出了错误的论点,声称他们通过 IDE 手动调试更有效,或者他们的编码技能很棒,他们不需要它。我承认这两个论点都是废话,特别是对于需要由多个开发人员维护的项目,但对 TDD 的任何有效反驳似乎很少见。

    所以这篇文章的重点是问,我是不是不明白如何使用 TDD 和自动单元测试?

    最佳答案

    你可以看看 sample ASP.NET MVC 2.0 project structure我写。它提供了一些可能让您开始对 Controller 逻辑和数据库进行单元测试的概念。就数据库测试而言,它不再是单元测试,而是集成测试。正如您将在我的示例中看到的,我使用的是 NHibernate,它允许我轻松切换到为每个测试装置重新创建的示例 SQLite 数据库。

    最后在 ASP.NET MVC 中进行单元测试可能会很痛苦,如果没有适本地分离关注点和抽象并使用模拟框架和框架,如 MVCContrib.TestHelper可以让你的生活更轻松。

    Here's a preview Controller 单元测试的样子。

    更新:

    作为对评论的回应,我认为编程是一项具体的任务,很难给出关于如何对复杂的业务应用程序进行单元测试的最终答案。为了能够测试复杂的应用程序层之间的耦合应该尽可能弱,这可以通过接口(interface)和抽象类来实现。我同意在复杂的应用程序中实现如此弱的耦合并不是一项微不足道的任务。

    我可以给你一个建议:如果整个 TDD 概念很难理解,而且你看不到它的好处,那么这没问题。没有人可以证明 TDD 在所有情况下都是有益的。只需尝试以每个类都有单一职责的方式设计您的应用程序。如果您发现自己在同一个类中进行输入验证、SQL 数据访问和异常处理,那么您就错了。一旦你实现了这种分离,你会发现单元测试变得更加容易,你甚至可以进入一个阶段,单元测试将插入你的开发:-)

    至于单元测试 JsonResultMvcContrib.TestHelper这是一个具体的问题,我给出了具体的答案:

    public class MyModel
    {
    public string MyProperty { get; set; }
    }

    public class HomeController : Controller
    {
    public ActionResult Index()
    {
    return Json(new MyModel { MyProperty = "value" });
    }
    }

    和测试:
    [TestMethod]
    public void HomeController_Index_Action_Should_Return_Json_Representation_Of_MyModel()
    {
    // arrange
    var sut = new HomeController();

    // act
    var actual = sut.Index();

    // assert
    actual
    .AssertResultIs<JsonResult>()
    .Data
    .ShouldBe<MyModel>("")
    .MyProperty
    .ShouldBe("value");
    }

    关于asp.net-mvc - 我只是不了解 TDD 单元测试(Asp.Net MVC 项目)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2867798/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com