Как разделить тесты, требующие совместного макета - PullRequest
0 голосов
/ 26 сентября 2018

Взгляните на этот тест Спока, который отлично работает, но тестирует несколько вещей в одном методе теста.

class WorkbookPoolSpec extends Specification {
    def 'test pool'() {
        setup:
            def workbook = Mock(Workbook)
            def workbookFactory = Mock(WorkbookFactory)
            def workbookPool = new WorkbookPool(workbookFactory)

        when:
            workbookPool.borrowWorkbook()
        then:
            1 * workbookFactory.create() >> workbook

        when:
            workbookPool.returnWorkbook(workbook)
        then:
            1 * workbook.reset()
    }
}

На самом деле мой тест намного длиннее, но должен работать на одном экземпляреWorkbookPool.

Я пытался разбить код ниже, но это не работает, потому что у вас не может быть @Shared Mocks, как я узнал из этого ответа: https://stackoverflow.com/a/41194168/923041

Есть ли любой способ избежать использования одного, большого метода тестирования со многими блоками когда / потом?

@Stepwise
class WorkbookPoolSpec extends Specification {
    @Shared
    def workbook = Mock(Workbook)

    @Shared
    def workbookFactory = Mock(WorkbookFactory)

    @Shared
    def workbookPool = new WorkbookPool(workbookFactory)

    def 'workbook is created on check-out'() {
        when:
            workbookPool.borrowWorkbook()
        then:
            1 * workbookFactory.create() >> workbook
    }

    def 'workbook is reset on check-in'() {
        when:
            workbookPool.returnWorkbook(workbook)
        then:
            1 * workbook.reset()
    }
}

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Вы можете использовать DetachedMockFactory вместе с @AutoAttach (новое в 1.2).

@Stepwise
class WorkbookPoolSpec extends Specification {
  @AutoAttach
  def workbook = MockHolder.workbook

  @AutoAttach
  def workbookFactory = MockHolder.workbookFactory

  @Shared
  def workbookPool = new WorkbookPool(MockHolder.workbookFactory)

  def 'workbook is created on check-out'() {
    when:
    workbookPool.borrowWorkbook()
    then:
    1 * workbookFactory.create() >> workbook
  }

  def 'workbook is reset on check-in'() {
    when:
    workbookPool.returnWorkbook(workbook)
    then:
    1 * workbook.reset()
  }

  static class MockHolder {
    static Workbook workbook = new DetachedMockFactory().Mock(Workbook)
    static WorkbookFactory workbookFactory = new DetachedMockFactory().Mock(WorkbookFactory)
  }
}
0 голосов
/ 26 сентября 2018

В моем понимании, весь смысл объявления имитации заключается в том, чтобы сказать: «Мои критерии проверки выполнения теста состоят в том, что фактические вызовы методов на фиктивных объектах проверяются» (в противном случае нет причин использовать mock).

Но если это так, то нет смысла в общих макетах, после того, как один тест сделан (проверки пройдены), макет становится неактуальным.

Теперь реальный вопрос заключается в том, почему вы говорите:«но нужно работать с одним экземпляром WorkbookPool».

Возможно, стоит подумать о рефакторинге кода, чтобы создание WorkbookPool (что, кстати, выглядит великолепно, потому что у него только одна зависимость) действительно будетлегкая задача, поэтому создание новых макетов для каждого отдельного теста станет не проблемой.

Этот способ должен отвечать необходимости модульного тестирования методов, предоставляемых объектом WorkbookPool

.один тест должен охватывать конец потока 2, затем, возможно, несколько, когда / тогда будет лучшим выбором, хотя я лично не используюэтот вид тестов

...