2013-12-06 4 views
9

Предположим, у меня был этот интерфейс и класс:Почему этот тест specs2 с использованием Mockito проходит?

abstract class SomeInterface{ 
    def doSomething : Unit 
} 

class ClassBeingTested(interface : SomeInterface){ 
    def doSomethingWithInterface : Unit = { 
    Unit 
    } 
} 

Обратите внимание, что метод doSomethingWithInterface фактически не делать ничего с интерфейсом.

создать тест для него, как это:

import org.specs2.mutable._ 
import org.specs2.mock._ 
import org.mockito.Matchers 
import org.specs2.specification.Scope 

trait TestEnvironment extends Scope with Mockito{ 
    val interface = mock[SomeInterface] 
    val test = new ClassBeingTested(interface) 
} 

class ClassBeingTestedSpec extends Specification{ 
    "The ClassBeingTested" should { 
    "#doSomethingWithInterface" in { 
     "calls the doSomething method of the given interface" in new TestEnvironment { 
     test.doSomethingWithInterface 
     there was one(interface).doSomething 
     } 
    } 
    } 
} 

Этот тест проходит. Зачем? Я устанавливаю это неправильно?

Когда я избавляюсь от объема:

class ClassBeingTestedSpec extends Specification with Mockito{ 
    "The ClassBeingTested" should { 
    "#doSomethingWithInterface" in { 
     "calls the doSomething method of the given interface" in { 
     val interface = mock[SomeInterface] 
     val test = new ClassBeingTested(interface) 
     test.doSomethingWithInterface 
     there was one(interface).doSomething 
     } 
    } 
    } 
} 

Тест терпит неудачу, как и ожидалось:

[info] x calls the doSomething method of the given interface 
[error]  The mock was not called as expected: 
[error]  Wanted but not invoked: 
[error]  someInterface.doSomething(); 

В чем разница между этими двумя тестами? Почему первый проходит, когда он терпит неудачу? Разве это не предназначено для использования Scopes?

ответ

14

Когда вы смешиваете черту Mockito с другим признаком, вы можете создавать ожидания, такие как there was one(interface).doSomething. Если такое выражение терпит неудачу, оно возвращает только Result, оно не выбрасывает Exception. Затем он теряется в Scope, потому что это просто «чистое» значение внутри тела признака.

Однако, если вы смешаете черту Mockito с номером mutable.Specification, тогда исключение будет сброшено при сбое. Это связано с тем, что класс mutable.Specification указывает, что должно быть ThrownExpectations путем смешивания в этом признаке.

Так что, если вы хотите создать признак расширения как Scope вы можете:

  1. создать черту внутри спецификации и не иметь его продлить Mockito:

    class MySpec extends mutable.Specification with Mockito { 
        trait TestEnvironment extends Scope { 
        val interface = mock[SomeInterface] 
        val test = new ClassBeingTested(interface) 
        } 
        ... 
    } 
    
  2. создать признак и спецификации, как вы, но вставляете org.specs2.execute.ThrownExpectations

    trait TestEnvironment extends Scope with Mockito with ThrownExpectations { 
        val interface = mock[SomeInterface] 
        val test = new ClassBeingTested(interface) 
    } 
    
    class MySpec extends mutable.Specification with Mockito { 
        ... 
    } 
    
Смежные вопросы