在执行可能最简单的操作时,在TDD或BDD中命名方法

时间:2011-04-19 12:41:38

标签: java junit tdd bdd

例如,我必须创建可以返回向量长度的Vector类。

首先我添加测试:

@Test
public void shouldReturnLengthOfVector() {
    Vector3D vector = new Vector3D(4d, 2d, -4d);

    assertThat(vector.length(), is(6d));
}

编写测试时,创建类Vector3D并添加方法存根。

public double length() {
    // TODO Auto-generated method stub
    return 0;
}

测试不通过。通过测试有什么简单的事情?硬编码值:

public double length() {
    return 6d;
}

测试通行证。现在我添加一些检查“cornercase”的方法:

@Test
public void someCornercaseShouldReturnLengthOfVector() {
    Vector3D vector = new Vector3D(1d, -2d, -2d);

    assertThat(vector.length(), is(3d));
}

当然没有通过。我改变了我的实现:

public double length() {
    return Math.sqrt(i * i + j * j + k * k);
}

一切都是绿色的!

当我遵循“可能工作的最简单的东西”原则时如何选择方法的名称?在这个示例方法someCornercaseShouldReturnLengthOfVector中,这不是好名字。

5 个答案:

答案 0 :(得分:2)

最简单的方法是向shouldReturnLengthOfVector添加另一个断言:

@Test
public void shouldReturnLengthOfVector() {
    Vector3D v1= new Vector3D(4d, 2d, -4d);
    assertThat(v1.length(), is(6d));

    Vector3D v2 = new Vector3D(1d, -2d, -2d);
    assertThat(v2.length(), is(3d));
}

我意识到有些人认为每个测试应该只有一个断言。但是,如果您提供几个“正常”操作的示例,并且为真正的极端情况保留单独的测试用例(例如,传递NaN),我认为作为行为文档更有用。

另一种方法是更具体地测试命名。在这种情况下,你不会创建一个测试“应该返回向量的长度”。相反,你要创建一堆方法,比如“相同的值是零长度”,“长度为1的向量”(可能有很多断言,改变不同的参数),“带负值的向量”,等等上。

答案 1 :(得分:1)

没有单元测试;这种方法的含义是否清楚。你必须使用你的判断。

最简单的名称只有l;)在确定可以使用的内容时,您还应该考虑清晰度。即你必须考虑开发人员以及编译器将让你逃脱的东西。

答案 2 :(得分:1)

您也可以重构您的测试代码。 someCornercaseShouldReturnLengthOfVector是一个完全有效的名称,而你处于“可能最有效的工作”阶段。重构该名称以反映代码在您的测试中进一步测试时实际测试的内容。

您还可以评论您的测试代码,以使其意图更加清晰。 ;)

答案 3 :(得分:0)

在命名我的方法时,我遵循以下模式:

WhatImTesting_WhatAreTheImputs_ExpectedResult

仅仅因为对你来说这是一个简单而明确的案例并不意味着对其他人而言。虽然我的方法命名可以变得冗长,但通常很清楚他们正在测试什么。为了使用你的例子,我只需要通过读取方法名称来命名我的方法类似于Length_ValidConstructorImputs_CorrectLength(),我知道我们正在使用有效输入(来自构造函数)测试长度方法,并且应该返回正确的长度。 / p>

另一个例子假设我想测试以下构造函数:

public class House
{
    Door theDoor;
    public House(Door aDoor)
    {
        if(aDoor == null)
        {
            throw new IllegalArgumentException();
        }
        theDoor = aDoor;
    }
}

我可能有两种方法来测试它:

  • Constructor_ValidDoor_ObjectCreated():这将检查构造函数参数有效时是否创建了House对象。
  • Constructor_NullDoor_ExceptionThrown():这将检查在将null参数传递给构造函数时抛出异常。

答案 4 :(得分:0)

我认为在这种情况下,我要么遵循Anon的建议并在同一个测试中放入第二个断言,整齐地避开命名问题,或者,如果宗教关于“每个测试的一个断言”规则,已经命名为下一个测试shouldReturnLengthOfAnotherVector