Тестовые возможности Scala с Mockito

#scala #mockito

#scala #mockito

Вопрос:

Я новичок в Scala. В настоящее время я тренируюсь для реализации макетного теста для черт. Может ли кто-нибудь помочь мне с реализацией? Я хочу издеваться над методами seasonalityDao.doSomeForB и seasonalityDao.doSomeForB1 внутри признака SeasonalityServiceImpl и тестировать метод hMock.doSomeForF().

Обновление: я исправил код в соответствии с комментариями ниже. В этом случае, когда я пытаюсь верифицировать очень много издевательских методов verify (sMock).doSomeForB() проверяет (sMock).doSomeForB1 (), я получаю следующую ошибку: Требуется, но не вызывается: seasonalityDao.doSomeForB(); -> в Main $$anonfun $ 1.примените $ mcV $ sp(Main.scala: 12) На самом деле, с этим макетом не было никаких взаимодействий.

Вот код (я только что упростил значительную часть проекта для примера):

 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. В чем именно заключается вопрос?

2. Как правильно реализовать макет теста для SeasonalityServiceImpl? В этом случае я получаю сообщение: Не удается подделать / шпионить класс Main $ $ anon $ 1 Mockito не может подделать / шпионить следующие: — конечные классы — анонимные классы — примитивные типы org.mockito.exceptions.base. Исключение MockitoException:…

3. Вам следует отредактировать вопрос и добавить эти ошибки. Люди с большей вероятностью ответят. Что касается самого вопроса, используйте classOf[SeasonalityService] вместо seasonality.getClass . При этом будет использоваться интерфейс, а не анонимный класс, который вы возвращаете ниже.

4. Спасибо за совет! В случае classOf [SeasonalityService] я получил: С параметром null Без параметра 0 возвращены значения по умолчанию, ожидаемые параметры (2) и 10

5. Ну, ты забыл высмеять этот объект (ты издеваешься, dMock но тестируешь hMock )

Ответ №1:

Если я правильно понимаю, вы ожидаете, что в вашем макете будут вызовы для doSomeForB и doSomeForB1 . Но ваш код проверяет это ожидание перед их вызовом, поэтому тест завершается неудачей.

Более того, ваши mocks определяются как локальные методы, что означает, что при каждом вызове вы получаете новый макет объекта. Вам нужно превратить их в локальные val, чтобы взаимодействовать (и проверять) с одним и тем же экземпляром.

Измените его, чтобы он выглядел как:

   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()
  }