单元测试和验证逻辑

Jac*_*obE 11 .net c# validation tdd unit-testing

我目前正在为包含验证例程的业务逻辑类编写一些单元测试.例如:

public User CreateUser(string username, string password, UserDetails details)
{
    ValidateUserDetails(details);
    ValidateUsername(username);
    ValidatePassword(password);

    // create and return user
}
Run Code Online (Sandbox Code Playgroud)

我的测试夹具是否应该包含对Validate*方法中可能出现的每个可能的验证错误的测试,或者最好将其留给一组单独的测试?或许验证逻辑应该以某种方式重构?

我的理由是,如果我决定测试CreateUser中可能发生的所有验证错误,那么测试夹具将变得非常臃肿.大多数验证方法都是在不止一个地方使用的......

在这种情况下有任何好的模式或建议吗?

Men*_*elt 11

每个测试应该只因一个原因而失败,因此只有一个测试失败.

这有助于编写一组可维护的单元测试.

我将为ValidateUserDetails,ValidateUsername和ValidateUserPassword分别编写几个测试.然后,您只需要测试CreateUser是否调用这些函数.


重读你的问题; 似乎我误解了一些事情.

您可能对JP Boodhoo在他的行为驱动设计风格上所写的内容感兴趣. http://blog.developwithpassion.com/2008/12/22/how-im-currently-writing-my-bdd-style-tests-part-2/

BDD正在成为一个非常重载的术语,每个人都有不同的定义和不同的工具来做到这一点.据我所知,JP Boodhoo正在做的是根据关注而不是上课来分割测试装置.

例如,您可以创建单独的灯具来测试用户详细信息的验证,用户名验证,密码验证和创建用户.BDD的想法是,通过命名testfixtures并以正确的方式测试,您可以通过打印出testfixture名称和测试名称来创建几乎像文档一样的东西.通过关注而不是按类分组测试的另一个优点是,您可能只需要为每个夹具设置一个设置和拆卸例程.

我自己也没有多少经验.

如果你有兴趣阅读更多内容,JP Boodhoo已经在他的博客上发布了很多相关内容(见上面的链接),或者你也可以听听Scott Bellware的dot net rocks剧集,在那里他谈到类似的分组和命名方式测试http://www.dotnetrocks.com/default.aspx?showNum=406

我希望这更像是你在寻找的东西.


Kon*_*rin 5

您肯定需要测试验证方法。

无需为所有可能的参数组合测试其他方法,只是为了确保执行验证。

您似乎在混合验证和合同设计。

验证通常用于友好地通知用户他的输入不正确。它与业务逻辑非常相关(密码不够强,电子邮件格式不正确等)。

契约式设计确保您的代码可以在稍后执行而不会抛出异常(即使没有它们,您也会得到异常,但要晚得多并且可能更模糊)。

关于应包含验证逻辑的应用程序层,可能最好的是服务层(由 Fowler 开发),它定义了应用程序边界并且是清理应用程序输入的好地方。并且在这个边界内不应该有任何验证逻辑,只有按合同设计来更早地检测错误。

所以最后,当你想友好地通知用户他错了时,编写验证逻辑测试。否则使用 Design By Contract 并继续抛出异常。