我正在寻找意见,以使用尽可能简单和尽可能少的代码来测试接口(interface)的不同实现。我已经实现了多种方法之一。我将使用继承来使其成为可能。
如果您在网上搜索这一点,您会发现许多文章告诉您包含继承是错误的,因为它更难阅读和理解,并且“始终”测试应该是一长段代码,而且它确实如此如果有很多重复的代码也没关系。 这种测试方式的好处之一是,借助 testImpls 必须实现的抽象方法,可以轻松测试实现之间的差异。
无论如何,我想听听您对我在这种情况下测试一个接口(interface)的两种不同实现的方式的看法。 impls 之间的区别在于,ImplCloud 将包放在云端,而 implLocal 将包放在磁盘上。
我们将有一个名为 SomeImplAsserts 的断言类以及 impl Local 和 Cloud。 该测试将由三个测试类构建,其中包含注释和一些用于解释的伪代码。
SomeImplAsserts.class
ImplCloudTest.class
ImplLocalTest.class
public abstract class SomeImplAsserts {
// Variables that booth implementations need.
private PathGetter pathGetter;
// Abstract helper methods.
abstract public String getLocalPackagePath(PathGetter pathGetter);
// Common setup method.
@Before
public void setUp() {
//Setup that's equal for for all impls will be done here.
}
@Test
public void testPackageContent() throws IOException {
// Place for common assert, asserts where we expect the same value from our implementations will be placed here.
String pathToPackage = getLocalPackagePath(pathGetter);
assertEquals("/someTempPath/package.zip", pathToPackage);
unzip(pathToPackage);
//asserts on package content.
}
//Common utility methods.
public void unzip(String abc) throws IOException {
// unzips the package
}
@After
public void tearDown() {
//Tear down of all tests will be done here.
}
}
实现云:
public class ImplCloudTest extends SomeImplAsserts {
@Override
public String getLocalPackagePath(PathGetter pathGetter) {
// A place where you could write specific asserts for this impl.
// This Impl puts an package in the cloud, in order to run tests on the content off the file
// we would like to put it on disk.
String url = pathGetter.getPath();
assertTrue(isUrl(url));
//Create temp dir and download file to it.
Path temp = Files.createTempDirectory("someTempPath");
URI u = URI.create(exportUrl);
InputStream in = u.toURL().openStream();
String pathToFile = temp.toString().concat("/" + exportUrl.substring(exportUrl.lastIndexOf("/")));
Files.copy(in, Paths.get(pathToFile));
return pathToFile;
}
}
实现本地:
public class ImplaLocalTest extends SomeImplAsserts {
@Override
public String getLocalPackagePath(PathGetter pathGetter) {
// this impl puts the file at the disk to begin with. No need to download it.
String localPath = pathGetter.getPath();
assertFalse(isUrl(localPath));
return localPath;
}
}
那么您认为,这是测试不同 impl 的好方法还是用两个来简化它来测试重复的断言会更好?
最佳答案
这里没有正确或错误的答案;这取决于偏好和具体情况。以下是关于一般方法的一些想法(全面披露:我强烈支持“组合击败继承”阵营):
基类中有两种类型的东西:
- 实用方法:这些方法并不真正属于类 - 只需将它们放入单独的类中,然后在具体的测试类中创建该类的实例即可。
设置/拆卸类型方法:这些可以位于基类中,但它不灵活,就像 Java 中的继承通常不灵活一样:您只能扩展一个类,所以如果你想添加更多类,你会有点卡住。
JUnit4 提供 Fixtures ,可以用来设置常用的东西;它们有点像 mixin。语法有点冗长,但繁琐也带来了灵 active 。
关于java - 带继承的 Junit 测试是好是坏?讨论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36857788/