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

How To Mock Out KafkaProducer Used Inside a Scala Class

我想为 Scala class 编写单元测试。 class 的目的是收集关于 Kafka 主题的指标和 post 它们。我试图在单元测试中模拟生产者以确保其余代码的完整性。下面是我的 class:

的简化版本
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() 命令,如果是,生产者是否记录符合预期。我一直没有成功找到自己的解决方案。谷歌搜索解决方案也没有结果。如果有人知道如何解决这个问题,我将不胜感激。

'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是否是预期的

希望对你有帮助