如何模拟在Scala类中使用的KafkaProducer

时间:2018-07-14 20:10:16

标签: scala unit-testing mocking mockito scalatest

我想为Scala类编写一个单元测试。该课程的目的是收集指标并将其发布到Kafka主题上。我试图在单元测试中模拟生产者,以确保其余代码的完整性。以下是我的课程的简化版本:

class MyEmitter(sparkConf: SparkConf) {
    <snip> -- member variables
    private val kafkaProducer = createProducer()

def createProducer(): Producer[String, MyMetricClass] = {
    val props = new Properties()
    ...
    Code to initialize properties
    ...

    new KafkaProducer[String, MyMetricClass](props)
}

def initEmitter(metricName: String): SomeClass = {
    // Some implementation
}

def collect(key: String, value: String): Unit = {
    // Some implementation
}

def emit(): Unit = {
    val record = new ProducerRecord("<topic name>", "<key>", "<value>")
    kafkaProducer.send(record)
}

我要在单元测试中做的是模拟生产者,并检查是否已调用 send()命令,如果是,则检查生产者记录是否符合期望。我一直找不到自己的解决方案。谷歌搜索解决方案也没有收获。如果有人知道如何解决该问题,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

'new'通常是测试的敌人,因此您应该提取该对象的创建内容,以便可以通过真实的KafkaProducer或模拟

在不更改界面的情况下进行操作的一种方法可能是

def createProducer(
        producer: Properties => KafkaProducer = props => new KafkaProducer[String, MyMetricClass](props)
        ): Producer[String, MyMetricClass] = {

   val props = new Properties()
   producer(props)
}

因此,在真实代码中,您会继续调用

myEmmiter.createProducer()

但是在测试中你会做

val producerMock = mock[KafkaProducer]    
myEmmiter.createProducer(_ => producerMock)

与此相关的另一个好处是,您还可以对函数本身进行加桩,以便可以验证您的方法创建的props是预期的

希望有帮助