用 JUnit 比较两个对象显示奇怪的行为
Comparing two objects with JUnit shows strange behaviour
我正在为 class AbsorptionScheme
编写一个 JUnit 测试方法,它采用所谓的 AbsorptionBlocks
并将它们分类到吸收块数组中。我想测试的是排序是否正常。所以我创建了两个 absorptionScheme 对象并用相同的 absorptionBlocks 填充,但第一个未排序,第二个已预排序。然后我想使用 JUnit 的 assertEquals(Object expected, Object actual)
函数来确保两个 AbsorptionScheme 对象是相同的。尽管 toSting 方法 returns 相同的字符串,JUnit 仍然告诉我两个对象不相同。
这是 JUnits 评估:
java.lang.AssertionError: expected: info.rueth.fpucalculator.calc.AbsorptionScheme<Absorption Scheme: (1FPU -> 3h) (2FPU -> 4h) (3FPU -> 5h) (4FPU -> 6h) (6FPU -> 8h)> but was: info.rueth.fpucalculator.calc.AbsorptionScheme<Absorption Scheme: (1FPU -> 3h) (2FPU -> 4h) (3FPU -> 5h) (4FPU -> 6h) (6FPU -> 8h)>
Expected :info.rueth.fpucalculator.calc.AbsorptionScheme<Absorption Scheme: (1FPU -> 3h) (2FPU -> 4h) (3FPU -> 5h) (4FPU -> 6h) (6FPU -> 8h)>
Actual :info.rueth.fpucalculator.calc.AbsorptionScheme<Absorption Scheme: (1FPU -> 3h) (2FPU -> 4h) (3FPU -> 5h) (4FPU -> 6h) (6FPU -> 8h)>
我能看到的唯一区别是 "expected" 字符串的末尾有一个空格,但 "actual" 字符串的末尾没有。
这是我要测试的 class:
package info.rueth.fpucalculator.calc;
import java.util.Arrays;
/**
* Holds an absorption scheme, connecting FPUs to recommended absorption times.
*/
public class AbsorptionScheme {
private AbsorptionBlock[] absorptionBlocks;
AbsorptionScheme() {
// Create empty array
absorptionBlocks = new AbsorptionBlock[0];
}
/**
* Adds a new absorption block to the absorption scheme.
* @param maxFPU The maximum FPU for the absorption time
* @param absorptionTime The absorption time for that FPU.
*/
public void addBlock(int maxFPU, int absorptionTime) {
// Copy existing array into new array with one more empty element at the end ...
AbsorptionBlock[] newArray = Arrays.copyOf(absorptionBlocks, absorptionBlocks.length + 1);
// ... and put new AbsorptionBlock into that empty element
newArray[absorptionBlocks.length] = new AbsorptionBlock(maxFPU, absorptionTime);
// Sort by maxFPU and replace object variable
Arrays.sort(newArray, new AbsorptionBlockSorter());
absorptionBlocks = newArray;
}
/**
* Picks the absorption time associated to the number of FPUs, e.g.:
* <p>absorptionScheme: 0-1 FPU - 3 hours; 1-2 FPU - 4 hours; 2-3 FPUs - 5 hours; 3-4 FPUs - 6 hours; >4 FPUs - 8 hours</p>
* <p>The fpu value is commercially rounded to 0 digits, i.e. 2.49 will be rounded to 2, 2.50 will be rounded to 3.</p>
* <p>If the fpu value is beyond the last scheme block, the time of the last scheme block in the array is returned.</p>
*
* @param fpus The calculated FPUs.
* @return The associated absorption time.
*/
public int getAbsorptionTime(double fpus) {
// Round up the fpus - it's more secure to get a longer insulin interval
long roundedFPUs = Math.round(fpus);
// Find associated absorption time
for (int i = 0; i < absorptionBlocks.length; i++) {
if (roundedFPUs <= absorptionBlocks[i].getMaxFPU()) {
return absorptionBlocks[i].getAbsorptionTime();
}
}
// Seems to be beyond the last block, so return time of the last block
return absorptionBlocks[absorptionBlocks.length - 1].getAbsorptionTime();
}
@Override
public String toString() {
String returnString = "Absorption Scheme:";
for (int i = 0; i < absorptionBlocks.length; i++) {
returnString += " (" + absorptionBlocks[i].getMaxFPU() + "FPU -> " + absorptionBlocks[i].getAbsorptionTime() + "h)";
}
return returnString;
}
}
这是我的测试代码:
@Test
public void addBlock() {
// Create absorption scheme
AbsorptionScheme absorptionSchemeActual = new AbsorptionScheme();
// Add absorption blocks - unsorted on purpose to test sorting!
absorptionSchemeActual.addBlock(2, 4);
absorptionSchemeActual.addBlock(3, 5);
absorptionSchemeActual.addBlock(6, 8);
absorptionSchemeActual.addBlock(1, 3);
absorptionSchemeActual.addBlock(4, 6);
// Create another absorption scheme ...
AbsorptionScheme absorptionSchemeExpected = new AbsorptionScheme();
// ... and add blocks, this time sorted!
absorptionSchemeExpected.addBlock(1, 3);
absorptionSchemeExpected.addBlock(2, 4);
absorptionSchemeExpected.addBlock(3, 5);
absorptionSchemeExpected.addBlock(4, 6);
absorptionSchemeExpected.addBlock(6, 8);
// Assert both schemes: They should be identical!
assertEquals(absorptionSchemeExpected, absorptionSchemeActual);
}
我看不出有什么不同,所以我做错了什么?
assertEquals(Object, Object)
方法使用给定对象的 equals()
来检查相等性。由于您没有在 AbsorptionScheme
class 中覆盖 equals()
,因此 assertEquals()
使用 java.lang.Object
的 equals()
实现。
Object.equals()
returns true
仅当两个对象相同时(相同的对象引用)。请参阅 Object.equals()
.
的 Javadoc 中的以下文本
The equals method for class Object implements the most discriminating
possible equivalence relation on objects; that is, for any non-null
reference values x and y, this method returns true if and only if x
and y refer to the same object (x == y has the value true).
在您的测试用例中,absorptionSchemeActual
和 absorptionSchemeExpected
是两个不同的对象。因此 assertEquals()
失败。
我正在为 class AbsorptionScheme
编写一个 JUnit 测试方法,它采用所谓的 AbsorptionBlocks
并将它们分类到吸收块数组中。我想测试的是排序是否正常。所以我创建了两个 absorptionScheme 对象并用相同的 absorptionBlocks 填充,但第一个未排序,第二个已预排序。然后我想使用 JUnit 的 assertEquals(Object expected, Object actual)
函数来确保两个 AbsorptionScheme 对象是相同的。尽管 toSting 方法 returns 相同的字符串,JUnit 仍然告诉我两个对象不相同。
这是 JUnits 评估:
java.lang.AssertionError: expected: info.rueth.fpucalculator.calc.AbsorptionScheme<Absorption Scheme: (1FPU -> 3h) (2FPU -> 4h) (3FPU -> 5h) (4FPU -> 6h) (6FPU -> 8h)> but was: info.rueth.fpucalculator.calc.AbsorptionScheme<Absorption Scheme: (1FPU -> 3h) (2FPU -> 4h) (3FPU -> 5h) (4FPU -> 6h) (6FPU -> 8h)>
Expected :info.rueth.fpucalculator.calc.AbsorptionScheme<Absorption Scheme: (1FPU -> 3h) (2FPU -> 4h) (3FPU -> 5h) (4FPU -> 6h) (6FPU -> 8h)>
Actual :info.rueth.fpucalculator.calc.AbsorptionScheme<Absorption Scheme: (1FPU -> 3h) (2FPU -> 4h) (3FPU -> 5h) (4FPU -> 6h) (6FPU -> 8h)>
我能看到的唯一区别是 "expected" 字符串的末尾有一个空格,但 "actual" 字符串的末尾没有。
这是我要测试的 class:
package info.rueth.fpucalculator.calc;
import java.util.Arrays;
/**
* Holds an absorption scheme, connecting FPUs to recommended absorption times.
*/
public class AbsorptionScheme {
private AbsorptionBlock[] absorptionBlocks;
AbsorptionScheme() {
// Create empty array
absorptionBlocks = new AbsorptionBlock[0];
}
/**
* Adds a new absorption block to the absorption scheme.
* @param maxFPU The maximum FPU for the absorption time
* @param absorptionTime The absorption time for that FPU.
*/
public void addBlock(int maxFPU, int absorptionTime) {
// Copy existing array into new array with one more empty element at the end ...
AbsorptionBlock[] newArray = Arrays.copyOf(absorptionBlocks, absorptionBlocks.length + 1);
// ... and put new AbsorptionBlock into that empty element
newArray[absorptionBlocks.length] = new AbsorptionBlock(maxFPU, absorptionTime);
// Sort by maxFPU and replace object variable
Arrays.sort(newArray, new AbsorptionBlockSorter());
absorptionBlocks = newArray;
}
/**
* Picks the absorption time associated to the number of FPUs, e.g.:
* <p>absorptionScheme: 0-1 FPU - 3 hours; 1-2 FPU - 4 hours; 2-3 FPUs - 5 hours; 3-4 FPUs - 6 hours; >4 FPUs - 8 hours</p>
* <p>The fpu value is commercially rounded to 0 digits, i.e. 2.49 will be rounded to 2, 2.50 will be rounded to 3.</p>
* <p>If the fpu value is beyond the last scheme block, the time of the last scheme block in the array is returned.</p>
*
* @param fpus The calculated FPUs.
* @return The associated absorption time.
*/
public int getAbsorptionTime(double fpus) {
// Round up the fpus - it's more secure to get a longer insulin interval
long roundedFPUs = Math.round(fpus);
// Find associated absorption time
for (int i = 0; i < absorptionBlocks.length; i++) {
if (roundedFPUs <= absorptionBlocks[i].getMaxFPU()) {
return absorptionBlocks[i].getAbsorptionTime();
}
}
// Seems to be beyond the last block, so return time of the last block
return absorptionBlocks[absorptionBlocks.length - 1].getAbsorptionTime();
}
@Override
public String toString() {
String returnString = "Absorption Scheme:";
for (int i = 0; i < absorptionBlocks.length; i++) {
returnString += " (" + absorptionBlocks[i].getMaxFPU() + "FPU -> " + absorptionBlocks[i].getAbsorptionTime() + "h)";
}
return returnString;
}
}
这是我的测试代码:
@Test
public void addBlock() {
// Create absorption scheme
AbsorptionScheme absorptionSchemeActual = new AbsorptionScheme();
// Add absorption blocks - unsorted on purpose to test sorting!
absorptionSchemeActual.addBlock(2, 4);
absorptionSchemeActual.addBlock(3, 5);
absorptionSchemeActual.addBlock(6, 8);
absorptionSchemeActual.addBlock(1, 3);
absorptionSchemeActual.addBlock(4, 6);
// Create another absorption scheme ...
AbsorptionScheme absorptionSchemeExpected = new AbsorptionScheme();
// ... and add blocks, this time sorted!
absorptionSchemeExpected.addBlock(1, 3);
absorptionSchemeExpected.addBlock(2, 4);
absorptionSchemeExpected.addBlock(3, 5);
absorptionSchemeExpected.addBlock(4, 6);
absorptionSchemeExpected.addBlock(6, 8);
// Assert both schemes: They should be identical!
assertEquals(absorptionSchemeExpected, absorptionSchemeActual);
}
我看不出有什么不同,所以我做错了什么?
assertEquals(Object, Object)
方法使用给定对象的 equals()
来检查相等性。由于您没有在 AbsorptionScheme
class 中覆盖 equals()
,因此 assertEquals()
使用 java.lang.Object
的 equals()
实现。
Object.equals()
returns true
仅当两个对象相同时(相同的对象引用)。请参阅 Object.equals()
.
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
在您的测试用例中,absorptionSchemeActual
和 absorptionSchemeExpected
是两个不同的对象。因此 assertEquals()
失败。