【问题标题】:how to phrase the result of an action in BDD/TDD如何在 BDD/TDD 中表达动作的结果
【发布时间】:2009-08-11 00:02:46
【问题描述】:

标题可能不是很清楚。我想到了以下示例:

Authenticator 对象使用凭据对用户进行身份验证。它返回一个 AuthResult 对象。此 AuthResult 对象表示身份验证成功或失败(如果是,则说明失败的原因,例如未找到用户名)。

如何在测试中表达这一点? 'testShouldReturnAuthObjectWithStatusSuccessOnValidLogin'?

【问题讨论】:

    标签: unit-testing testing tdd naming bdd


    【解决方案1】:

    testValidLoginIsSuccessfultestIsSuccessfulOnValidLogin 对我来说似乎已经足够了。

    对于错误测试,您可以使用类似 testGetsCustomMessageOnUserNotFound

    您应该避免将实现细节放在方法名称中。

    【讨论】:

    • 假设这个 Authenticator 使用其他一些具有指定职责的类来完成一些工作(例如连接到数据库)。如果我为这些类编写测试,这是否意味着我放弃了“完整身份验证包”的实现细节?
    • 不,我只是在谈论方法名称。如果您想对其进行单元测试,您可能应该模拟这些其他类。然后你单独测试那些其他类,看看它们是否单独工作
    • 一个“完整的身份验证包”将是一个集成测试。您将测试这些类是否连接良好以及整个过程是否有效。在这种情况下,更建议它的名称不是特定于实现的。
    【解决方案2】:

    没有看到这些测试是如何实现的,从命名看来,观察结果是过度包装的。

    如果此测试失败,您将不得不进行一些挖掘以了解是否是因为 (a) 没有返回 AuthResult 对象,或者 (b) 状态不是“成功”,此外,是否没有 AuthResult 是因为Authenticator 从未连接到数据库或执行其他一些必需的操作?

    我将夹具命名为When_told_to_authenticate_with_valid_credentials,然后将断言分成两个不同的观察结果:
    1. should_return_an_AuthResult
    2. 应该_be_successful

    如果您按照 Samuel 的正确建议模拟其他类,则可以进一步规定 Authenticator 的行为符合您的预期:
    3. should_connect_to_the_database
    4.

    【讨论】:

    • should_return_an_AuthResult 不是实现细节吗?
    • 是的,这是一个实现细节。我不同意实现细节不应该包含在 TEST 方法的名称中的前提,因为(1)它正是您关注的实现,并且在关注行为(而不是状态)时正在测试,(2 ) 方法名称因此应该清楚地反映什么是通过或失败,并且 (3) 测试程序集没有发布或部署。
    • 我不同意第 1 点。如果我的测试确认我的方法工作正常,我不在乎实现是什么。如果我的测试对实现做出假设,那么如果我以后决定重构实现,我可能会破坏测试。
    • @JeffH AuthResult 将是一个接口。如果这种情况发生变化,严格来说它不会是重构,我希望在这种情况下会破坏一些测试。
    猜你喜欢
    • 2011-09-21
    • 2011-06-10
    • 2016-02-18
    • 2011-05-22
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    相关资源
    最近更新 更多