0

我正在尝试根据给定的 JUnit 创建位置、长度和圆类,以便最终以图形方式输出它们。但是我现在被困在其中一种方法中好几天了。我试图截断精度,但后来我的 equals 方法失败了。

规模的 JUnit:

public void testScale(){
    Length inch2 = Length.unit.scale(320.0);
    assertTrue(inch2 != null);
    assertEquals(Length.inch,inch2);
    assertFalse(inch2.equals(Length.unit)); 
    Length unit2 = Length.cm.scale(1.0/125.98425197);
    assertTrue(unit2 != null);
    assertEquals(Length.unit,unit2); // This is the line my scale method fails
                                     // Here my unit2 has a length of 1.0001249999881234
                                     // and my constant cm has a length of 1.0 but 
                                     // truncating those precisions caused my equals                                   
                                     // method to fails.  
    assertFalse(unit2.equals(Length.cm));
    Length z = Length.meter.scale(0);
    assertTrue(z != null);
    assertEquals(Length.zero,z);
    assertFalse(z.equals(Length.meter));
    assertFalse(Length.zero.equals(null));
}

我的缩放方法:

public Length scale(double d) {
    if (d < 0)
        throw new IllegalArgumentException();
    else {
        return new Length(d* this.length);
    }
}

我怀疑问题可能来自我的 equals 方法,但在给定的 JUnit 中它通过了测试。

用于等于的 JUnit:

public void testEquals(){
    assertFalse(Length.unit.equals("Not a length"));
    assertFalse(Length.inch.equals(null));
    assertEquals(Length.zero,Length.unit.scale(0.0000001));
    assertTrue(Length.unit.scale(0.0000001).compareTo(Length.zero) == 0);
    assertTrue(Length.zero.compareTo(Length.unit.scale(0.0000001)) == 0);
    assertFalse(Length.unit.scale(0.0000015).equals(Length.zero));
    assertTrue(Length.unit.scale(0.0000015).compareTo(Length.zero) > 0);
    assertTrue(Length.zero.compareTo(Length.unit.scale(0.0000015)) < 0);
}

我的等于方法:

@Override
public boolean equals(Object other) {
    if (other == null || !(other instanceof Length)) {
        return false;
    }
    Length o = (Length) other;
    if (Math.abs(this.length - o.length) < 0.000001) {
        return true;
    } else {
        return false;
    }
}

请帮忙


我所有代码的链接: https ://www.dropbox.com/sh/bz400f8y0ufx381/59aUTilrBt

4

1 回答 1

1

你一次测试了太多东西。

单元测试应该是一个代码单元——代码的一个方面,而不是一次所有的事情。

我还注意到您的任何测试方法都没有用@Test;注释。您应该使用 JUnit4 测试来执行此操作。

scale因此,对于您的第一次测试,您需要练习一个相对较小的方法。让我们列举案例:

  • d < 0. 我应该期待一个IllegalArgumentException.
  • d >= 0. 我应该期望一个新实例的Length大小是该实例的倍数,d并且无论实例的设定长度是多少。

这看起来是两个离散的测试:

@Test(expected = IllegalArgumentException.class)
public void scaleShouldThrowExceptionWhenInvalidLength() {

}

@Test
public void scaleShouldBehaveNormally() {

}

我让你填写空白,因为我不知道scale附加到什么对象。

Equals 也是同样的方法——你想执行等价的每个条件。

顺便说一句,您可以return Math.abs(this.length - o.length) < 0.000001根据自己的条件去做。 return truereturn false尖叫不好的做法。

  • 您传入的对象是null.
  • 您传入的对象不是Length.
  • 您传入的对象失败Math.abs(this.length - o.length) < 0.000001
  • 您传入的对象 pass Math.abs(this.length - o.length) < 0.000001

所以上面是四个离散的测试。

@Test
public void equalsShouldFailIfNull() {

}

@Test
public void equalsShouldFailIfNotInstanceOfLength() {

}

@Test
public void equalsDoesNotMeetCondition() {

}

@Test
public void equalsMeetsCondition() {

}

填空,我留给读者作为练习。

处理浮点数时要非常小心。你不会总是得到一个精确的表示(也就是说,在处理分数时你可能会得到一个不精确的值)。确保您的 equals 方法定义明确,以尊重当您没有精确的十进制值时可能发生的情况。

或者,如果您确实需要小数精度,请使用 aBigDecimal代替。

于 2013-09-08T04:19:34.883 回答