字数单元测试(Scala JUnit)

例如,我们有 WordCountServicecountWords 方法:

class WordCountService {
    def countWords(url: String): Map[String, Int] = {
        val sparkConf = new SparkConf().setMaster("spark://somehost:7077").setAppName("WordCount"))
        val sc = new SparkContext(sparkConf)
        val textFile = sc.textFile(url)
        textFile.flatMap(line => line.split(" "))
                .map(word => (word, 1))
                .reduceByKey(_ + _).collect().toMap
    }
}

这项服务看起来非常难看,不适合单元测试。应该将 SparkContext 注入此服务。可以使用你最喜欢的 DI 框架访问它,但为了简单起见,它将使用构造函数实现:

class WordCountService(val sc: SparkContext) {
    def countWords(url: String): Map[String, Int] = {
        val textFile = sc.textFile(url)
        textFile.flatMap(line => line.split(" "))
                .map(word => (word, 1))
                .reduceByKey(_ + _).collect().toMap
    }
}

现在我们可以创建简单的 JUnit 测试并将可测试的 sparkContext 注入 WordCountService:

class WordCountServiceTest {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("WordCountTest")
    val testContext = new SparkContext(sparkConf)
    val wordCountService = new WordCountService(testContext)

    @Test
    def countWordsTest() {
        val testFilePath = "file://my-test-file.txt"

        val counts = wordCountService.countWords(testFilePath)

        Assert.assertEquals(counts("dog"), 121)
        Assert.assertEquals(counts("cat"), 191)
    }
}