java重载静态导入
在测试类中,我想为我自己的assertEquals
重载提供一些不依赖Object.equals
的特殊逻辑。不幸的是,这不起作用,因为只要我在本地声明assertEquals
方法,Java就再也找不到来自org.junit.Assert.*
的静态导入
有办法吗?也就是说,有没有办法为静态导入的方法提供额外的重载?(比较明显的解决方案是用不同的方法命名,但这种解决方案没有相同的审美吸引力。)
我的测试类文件如下所示:
package org.foo.bar;
import static org.junit.Assert.*;
import org.junit.Test;
public class BarTest {
private static void assertEquals(Bar expected, Bar other) {
// Some custom logic to test equality.
}
@Test
public void testGetFoo() throws Exception {
Bar a = new Bar();
assertEquals(42, a.getFoo()); // Error *
}
@Test
public void testCopyConstructor() throws Exception {
Bar a = new Bar();
// Fill a.
Bar b = new Bar(a);
assertEquals(a, b);
}
}
Error *
是“类型BarTest
中的方法assertEquals(Bar, Bar)
不适用于参数(int, int)
。”
# 1 楼答案
唯一的办法是完全限定其中一个
# 2 楼答案
这个答案有两个部分——一个是关于编译错误的,另一个是关于assertEquals()的使用
问题在于,在两个不同的名称空间中有两个assertEquals()方法——一个存在于组织中。朱尼特。断言名称空间,组织中的另一个名称空间。福。酒吧BarTest名称空间(当前名称空间)
由于shadowing rules declared in the Java Language Specification错误,编译器会报告该错误。Assert的静态导入。assertEquals()被BarTest类中声明的assertEquals()隐藏
修复方法(总是在隐藏声明的情况下)是使用FQN(完全限定名)。如果您打算使用assertEquals(…)对于JUnit Assert类,使用
当你需要使用你的声明时,只需使用
只在巴特斯特,那里有阴影。在所有其他只需要两个断言之一的类中。assertEquals()或BarTest。asserEquals(),您可以导入Assert或BarTest(我认为您不需要在其他地方导入BarTest,但还是声明了这一点)
当没有阴影时,您可以简单地导入类或静态方法并在没有FQN的情况下使用它
需要考虑的其他事情
断言。assertEquals()在内部使用参数类的equals()方法。在测试用例中声明assertEquals()违反了DRY原则,因为类型为equals()的方法应该得到一致的实现和使用——在源代码和单元测试中使用两种不同的实现必然会导致混淆
最好的方法是在Bar上实现equals(),然后使用Assert。测试用例中的assertEquals()。如果你已经有了,你就不需要物物交换。assertEquals()。assertEquals()的伪代码有点像下面的代码
# 3 楼答案
或者
我会选择第一个方法,因为尽管它是一个静态方法,但必须有一个实例才能使用它(它是私有的),而且
this
不会受到未来重命名的奇想的影响# 4 楼答案
对于在单元测试中调用
assertEquals(Bar, Bar)
的特定示例,一个可能的解决方案是使用提供静态方法的类来扩展该类,如下所示:然后可以包含
import static BarAssert.assertEquals;
并使用自定义逻辑抱歉,这并没有直接回答问题,而且更针对你的例子。根据我对问题的评论,我建议反对这种做法