Як зробити екземпляр перевірки за допомогою Scala (Test)


100

Я намагаюся включити ScalaTest у свій проект Java; заміни всіх тестів JUnit на ScalaTests. В один момент я хочу перевірити, чи вводить ін'єктор Гіса правильний тип. У Java у мене є такий тест:

public class InjectorBehaviour {
    @Test
    public void shouldInjectCorrectTypes() {
        Injector injector = Guice.createInjector(new ModuleImpl());
        House house = injector.getInstance(House.class);

        assertTrue(house.door() instanceof WoodenDoor);
        assertTrue(house.window() instanceof BambooWindow);
        assertTrue(house.roof() instanceof SlateRoof);
    }
}

Але у мене є проблема зробити те ж саме з ScalaTest:

class InjectorSpec extends Spec {
    describe("An injector") {
        it("should inject the correct types") {
            val injector = Guice.createInjector(new ModuleImpl)
            val house = injector.getInstance(classOf[House])

            assert(house.door instanceof WoodenDoor)
            assert(house.window instanceof BambooWindow)
            assert(house.roof instanceof SlateRoof)
        }
    }
}

Він скаржиться, що цінність instanceofне є членом Door/ Window/ Roof. Чи не можу я використовувати instanceofтакий спосіб у Scala?

Відповіді:


114

Скала - це не Java. Скала просто не має оператора, instanceofнатомість має параметричний метод, який називається isInstanceOf[Type].

Можливо, вам також сподобається перегляд курсу ScalaTest Crash .


6
добре, це насправді не відповідає на питання. ScalaTest має вбудовану підтримку для перевірки типу. Дивіться відповідь від @ martin-g
maasg

Як це зробити, якщо "Введіть" це ознака?
Лобо

Не впевнений , якщо я правильно розумію, але це повинно бути те ж саме: isInstanceOf[TraitName].
agilesteel

88

За допомогою програми Scalatest 2.2.x (можливо, навіть раніше) ви можете використовувати:

anInstance mustBe a[SomeClass]

4
Це рекомендований підхід для останніх версій ScalaTests
maasg

6
також доступні, a[Type]щоб ви могли бути граматично правильними;)
Самуїл

Я це шукав! :)
Atais

22
tiger shouldBe a [Tiger]це поточний синтаксис scalatest.org/at_a_glance/FlatSpec
jhegedus

2
@jhegedus mustBeтакож правильний, якщо ви використовуєте doc.scalatest.org/3.0.1/#org.scalatest.MustMatchers, який ви хочете отримати для FreeSpec.
Тобі

30

Якщо ви хочете бути меншими за розміром JUnit-esque і якщо ви хочете використовувати відповідники ScalaTest, ви можете написати власний відповідник властивостей, що відповідає типу (стирання типу бар).

Я вважаю цю тему дуже корисною: http://groups.google.com/group/scalatest-users/browse_thread/thread/52b75133a5c70786/1440504527566dea?#1440504527566dea

Потім ви можете написати такі твердження, як:

house.door should be (anInstanceOf[WoodenDoor])

замість

assert(house.door instanceof WoodenDoor)

+1 Це виглядає дуже приємно і навіть зрозуміло для людей, які не програмують (якщо припустити, що вони знають, що таке екземпляр :-)).
helpermethod

Якщо синтаксис цукру - це те, що ви шукаєте, за допомогою певного рефакторингу ви, можливо, зможете написати house.door повинен бути (madeOf [Wood]) або house.door повинен бути (madeOf [Bamboo]).
Гійом Белроуз


16

Поточні відповіді про isInstanceOf [Type] та поради з юніту хороші, але я хочу додати одне (для людей, які потрапили на цю сторінку в якості не пов’язаного з юнітом). У багатьох випадках відповідність шаблону шкали відповідає вашим потребам. Я рекомендував би його в тих випадках, оскільки він надає вам безкоштовну клавіатуру та залишає менше можливостей для помилок.

Приклад:

OuterType foo = blah
foo match {
  case subFoo : SubType => {
    subFoo.thingSubTypeDoes // no need to cast, use match variable
  }
  case subFoo => {
    // fallthrough code
  }
}

Рекомендований спосіб перевірити відповідність шаблону в ScalaTest - використовувати inside(foo)замість `foo match). Дивіться scalatest.org/user_guide/using_matchers#matchingAPattern
Rich Dougherty

3

Консолідація посилань на обговорення Гілаума ScalaTest (та ще одна дискусія, пов’язана з Джеймсом Муром) у два методи, оновлені для ScalaTest 2.x та Scala 2.10 (для використання ClassTag, а не для маніфесту):

import org.scalatest.matchers._
import scala.reflect._

def ofType[T:ClassTag] = BeMatcher { obj: Any =>
  val cls = classTag[T].runtimeClass
  MatchResult(
    obj.getClass == cls,
    obj.toString + " was not an instance of " + cls.toString,
    obj.toString + " was an instance of " + cls.toString
  )
}

def anInstanceOf[T:ClassTag] = BeMatcher { obj: Any =>
  val cls = classTag[T].runtimeClass
  MatchResult(
    cls.isAssignableFrom(obj.getClass),
    obj.getClass.toString + " was not assignable from " + cls.toString,
    obj.getClass.toString + " was assignable from " + cls.toString
  )
}

2

Я використовую 2.11.8 для твердження з колекціями. Новіший синтаксис такий:

val scores: Map[String, Int] = Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8)
scores shouldBe a[Map[_, _]] 

3
Через стирання ви не можете перевірити Mapпараметри типу. Те, що ви написали, те саме, що писати scores shouldBe a[Map[_, _]]. Про це йдеться тут: scalatest.org/user_guide/using_matchers#checkingAnObjectsClass
Rich Dougherty
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.