0
votes

I'm new one in Scala. Currently I'm traing to implement a mock test for traits. Can somebody help me with implementation? I want to mock the methods seasonalityDao.doSomeForB and seasonalityDao.doSomeForB1 inside of the trait SeasonalityServiceImpl and test method hMock.doSomeForF().

Update: I have corrected the code according comments below. In this case, when I try to veryfy mocked methods verify(sMock).doSomeForB() verify(sMock).doSomeForB1(), I receive next error: Wanted but not invoked: seasonalityDao.doSomeForB(); -> at Main$$anonfun$1.apply$mcV$sp(Main.scala:12) Actually, there were zero interactions with this mock.

Here is a code(I have just simplified significant part of project for an example):

import org.scalatest._
import org.mockito.Mockito._

class Main extends FunSuite with SeasonalityServiceComponentImpl with SeasonalityDaoComponent {
  test("some test") {
    def hMock = mock(classOf[SeasonalityServiceImpl])
    def sMock = mock(classOf[SeasonalityDao])

    when(sMock.doSomeForB()).thenReturn(Option(2))
    when(sMock.doSomeForB1()).thenReturn(10)

    verify(sMock).doSomeForB()
    verify(sMock).doSomeForB1()

    println("With Option " + hMock.doSomeForF())
    println("Without Option " + hMock.doSomeForF1())
  }

  override def seasonalityDao: SeasonalityDao = mock(classOf[SeasonalityDao])

  override def seasonalityService: SeasonalityService = mock(classOf[SeasonalityService])
}

trait SeasonalityDaoComponent {
  def seasonalityDao: SeasonalityDao

  trait SeasonalityDao {
    def doSomeForB(): Option[Int]
    def doSomeForB1(): Int
  }
}

trait SeasonalityServiceComponent {
  def seasonalityService: SeasonalityService

  trait SeasonalityService {
    def doSomeForF(): Option[Int]
    def doSomeForF1(): Int
  }
}

trait SeasonalityServiceComponentImpl extends SeasonalityServiceComponent {
  this: SeasonalityDaoComponent =>

  trait SeasonalityServiceImpl extends SeasonalityService {
    def doSomeForF(): Option[Int] = {
      seasonalityDao.doSomeForB()
    }
    def doSomeForF1(): Int = {
      seasonalityDao.doSomeForB1()
    }
  }
}
1
What exactly is the question?Iulian Dragos
How correct implement mock test for the SeasonalityServiceImpl? In this case I receive the message:Cannot mock/spy class Main$$anon$1 Mockito cannot mock/spy following: - final classes - anonymous classes - primitive types org.mockito.exceptions.base.MockitoException:...Nikolay
You should edit the question and add these errors. People will be more likely to answer. As to the question itself, use classOf[SeasonalityService] instead of seasonality.getClass. That will use the interface, instead of the anonymous class you return below.Iulian Dragos
Thank you for advice! In case of classOf[SeasonalityService], I received: With Option null Without Option 0 Returned default values, expected Option(2) and 10Nikolay
Well, you forgot to mock that object (you're mocking dMock but testing hMock)Iulian Dragos

1 Answers

2
votes

If I understand correctly, you expect to have calls on your mock for doSomeForB and doSomeForB1. But your code verifies this expectation before you call them, so the test fails.

Moreover, your mocks are defined as local methods, meaning on each invocation you get a new mock object. You need to turn them into local vals, so you interact (and verify) the same instance.

Modify it to look like:

  test("some test") {
   // this seems unused -->>  def hMock = mock(classOf[SeasonalityServiceImpl])
    val sMock = mock(classOf[SeasonalityDao]) // you need it to be a val, not a def

    when(sMock.doSomeForB()).thenReturn(Option(2))
    when(sMock.doSomeForB1()).thenReturn(10)

    println("With Option " + sMock.doSomeForF()) // note that you should call them on sMock
    println("Without Option " + sMock.doSomeForF1())

    verify(sMock).doSomeForB()
    verify(sMock).doSomeForB1()
  }