nads
nads

Reputation: 388

How To Mock Out KafkaProducer Used Inside a Scala Class

I want to write a unit test for a Scala class. The purpose of the class is to collect metrics and post them on a Kafka topic. I am trying to mock the producer in the unit test to ensure sanity of the rest of the code. Below is a simplified version of my 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)
}

What I would like to do in my unit test is to mock out the producer and check whether the send() command has been called and, if so, whether the producer record matches the expectation. I have been unsuccessful to find a solution on my own. Googling the solution has also been unfruitful. If anyone knows how the problem could be solved, I will be most grateful.

Upvotes: 5

Views: 2305

Answers (1)

ultrasecr.eth
ultrasecr.eth

Reputation: 1497

'new' is generally an enemy of testing, so you should extract the creation of that object so you can either pass a real KafkaProducer or a mock

One way to do it without changing the interface could be

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

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

So then in real code you keep calling

myEmmiter.createProducer()

But in test you'd do

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

Another good thing about this is that you could also stub the function itself so you can verify that the props your method creates are the expected ones

Hope it helps

Upvotes: 4

Related Questions