【问题标题】:why would I unit test business layer in MVP为什么我要在 MVP 中对业务层进行单元测试
【发布时间】:2012-03-28 08:36:05
【问题描述】:

我在业务逻辑层创建了以下示例方法。我的数据库不允许名称和父列为空:

public void Insert(string catName, long catParent)
{
    EntityContext con = new EntityContext();
    Category cat = new Category();
    cat.Name = catName;
    cat.Parent = catParent;
    con.Category.AddObject(cat);
    con.SaveChanges();
}

所以我对此进行单元测试并测试空名称和空父级将失败。为了解决这个问题,我必须重构插入方法如下:

public void Insert(string catName, long catParent)
{
    //added to pass the test
    if(string.IsNullOrEmpty(catName)) throw new InvalidOperationException("wrong action. name is empty.");
    long parent;
    if(long.TryParse(catParent, out parent) == false) throw new InvalidOperationException("wrong action. parent didn't parsed.");
    //real bussiness logic
    EntityContext con = new EntityContext();
    Category cat = new Category();
    cat.Name = catName;
    cat.Parent = parent;
    con.Category.AddObject(cat);
    con.SaveChanges();
}

我的整个业务层都是对数据库的简单调用。所以现在我再次验证数据!我已经计划在 UI 中进行验证并在 UI 测试单元中测试这类东西。除了验证相关任务之外,我应该在我的业务逻辑方法中测试什么?如果没有要进行单元测试的东西,为什么每个人都说“对所有层进行单元测试”以及我在网上找到很多类似的东西?

【问题讨论】:

    标签: asp.net unit-testing testing webforms mvp


    【解决方案1】:

    测试涉及的技术是将程序分解成更小的部分(更小的组件甚至类)并测试这些小部分。当您将这些部分组装在一起时,您会进行不太全面的测试 - 较小的部分已经被证明可以工作 - 直到您拥有一个功能性的、经过测试的程序,然后您将其提供给用户进行“用户测试”。

    最好测试较小的部分,因为:

    1. 编写测试更简单。你需要更少的数据,你只需要设置一个对象,你必须注入更少的依赖。

    2. 更容易确定要测试的内容。您可以通过简单阅读代码(或者更好的是,通过技术规范)了解失败的条件。

    现在,您如何保证您的业务层(尽管如此简单)得到正确实施?如果写得不好,即使是简单的数据库插入也会失败。此外,您如何保护自己免受变化?没错,代码是可以的,但是以后如果数据库发生变化或者有人更新业务逻辑会发生什么。

    但是,这很重要,您实际上不需要测试所有内容。使用你的直觉(也称为经验)来了解什么需要测试,什么不需要。如果您的方法足够简单,只需确保正确测试了客户端代码。

    最后,您说过所有验证都将在 UI 中进行。业务层应该能够验证数据以增加应用程序的重用性。如果不这样做,那么无论何时您或将来对您的代码进行更改的任何人都可能会创建新的 UI 并忘记添加所需的验证。

    【讨论】:

    • 感谢您的回答。您的所有观点都是正确的,但我选择 UI 进行验证,因为:首先,可以有客户端通知,其次,它会更快地给出响应,这意味着如果出现问题,页面加载速度会更快。另一种方法是将验证分解为 UI 和 bll,UI 只验证简单的逻辑,而 bll 验证复杂的规则,但我发现这违背了单一责任,而且对于简单的事情来说过于复杂。
    • @jim,在我当前的项目中,我们有一个远程后端执行业务规则。我们在前端进行所有可能的验证以节省网络带宽和往返时间,这符合用户和企业的最大利益。我们只验证我所说的规则:例如,最小值必须始终小于或等于最大值,未来事件必须有未来日期等。业务规则不会改变这种事情.但是,后端必须再次验证所有内容,因为它不能依赖我的实现。
    • 因为您有一个远程后端,我看不到您的项目有任何其他解决方案,但是单一责任呢?您的方法在层级上没有违反该原则吗?
    • @Jim 您应该始终验证 UI 以保护您的应用程序免受用户发送不良数据的影响并提供更好的用户体验。您始终需要在业务层进行验证,以保护您的应用程序免受可能篡改请求的黑客的攻击,并且他们可能能够绕过在表示层设置的验证并验证复杂的业务规则,这是其中之一该层的目的。如果您的业务类调用验证类来履行该职责,则不会违反单一职责原则。
    • 非常感谢塞尔吉奥的评论。现在每个业务类都有不同的验证。所以对于每个 bll 类我需要一个不同的验证类?或者有其他方法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多