我想运行单元测试,但我需要一个org.apache.hadoop.fs.FileSystem实例。 是否有任何模拟或任何其他解决方案来创建FileSystem?
答案 0 :(得分:17)
如果您正在使用hadoop 2.0.0及更高版本 - 请考虑使用hadoop-minicluster
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-minicluster</artifactId>
<version>2.5.0</version>
<scope>test</scope>
</dependency>
有了它,您可以在本地计算机上创建临时hdfs,并在其上运行测试。 setUp方法可能如下所示:
baseDir = Files.createTempDirectory("test_hdfs").toFile().getAbsoluteFile();
Configuration conf = new Configuration();
conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, baseDir.getAbsolutePath());
MiniDFSCluster.Builder builder = new MiniDFSCluster.Builder(conf);
hdfsCluster = builder.build();
String hdfsURI = "hdfs://localhost:"+ hdfsCluster.getNameNodePort() + "/";
DistributedFileSystem fileSystem = hdfsCluster.getFileSystem();
在tearDown方法中,您应该关闭mini hdfs群集,并删除临时目录。
hdfsCluster.shutdown();
FileUtil.fullyDelete(baseDir);
答案 1 :(得分:7)
看看hadoop-test jar
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-test</artifactId>
<version>0.20.205.0</version>
</dependency>
它已被归类为设置MiniDFSCluster和MiniMRCluster,因此您可以在没有hadoop的情况下进行测试
答案 2 :(得分:5)
为什么不使用像Mockito或PowerMock这样的模拟框架来模拟与FileSystem的交互?您的单元测试不应该依赖于实际的FileSystem,而应该只是在与FileSystem交互时验证代码中的行为。
答案 3 :(得分:2)
一种可能的方法是在Junit 4.7中使用 TemporaryFolder 。
请参阅:http://www.infoq.com/news/2009/07/junit-4.7-rules或http://weblogs.java.net/blog/johnsmart/archive/2009/09/29/working-temporary-files-junit-47。
答案 4 :(得分:1)
我做了什么(直到找到更好的解决方案)我扩展了FileSystem。
答案 5 :(得分:0)
您可能想看看RawLocalFileSystem。虽然我认为你最好嘲笑它。
答案 6 :(得分:0)
您可以使用HBaseTestingUtility:
time { echo "hi" & sleep 5 & wait -n && wait -n && echo "ok"; } &> time.log
答案 7 :(得分:0)
添加以下依赖项
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-minicluster</artifactId>
<version>2.7.3</version>
<!-- <scope>test</scope>-->
</dependency>
添加以下代码,它将创建FileSysetm。
import java.nio.file.{Files, Paths}
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.hdfs.MiniDFSCluster
object MiniClusterDemo extends App {
def sysDir: String = System.getProperty("user.dir")
if(miniCluster!=null) println("Cluster created and active") else println("something went wrong")
def miniCluster: FileSystem = {
val basePath = Paths.get(s"$sysDir")
val baseDir = Files.createTempDirectory(basePath,"hdfs_test").toFile.getAbsoluteFile
val conf = new Configuration()
conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, baseDir.getAbsolutePath)
val hdfsCluster = new MiniDFSCluster.Builder(conf).build()
val hdfsURI = s"hdfs://localhost:${hdfsCluster.getNameNodePort}/"
val fileSystem = hdfsCluster.getFileSystem
//hdfsCluster.shutdown();
//FileUtil.fullyDelete(baseDir);
fileSystem
}
}
创建MiniCluster后查看示例日志
答案 8 :(得分:0)
我的解决方案是创建一个扩展抽象Hadoop FileSystem的DummyFileSystem
,因此我可以伪造文件是否存在等...
“所有文件都存在”的示例:
@Override
public FileStatus getFileStatus(Path f) throws IOException {
return new FileStatus(10, false, 3, 128*1024*1024,1,1, null, null, null, f);
}
我发现更容易控制伪造数据。
答案 9 :(得分:0)
我用sbt尝试了Thirupathi Chavati和Alexander Tokarev解决方案,并且:
libraryDependencies += "org.apache.hadoop" % "hadoop-hdfs" % "2.8.1" classifier "tests"
只能通过添加以下内容来工作:
libraryDependencies += "org.apache.hadoop" % "hadoop-common" % "2.8.1" classifier "tests"
{{1}}