2011-12-19 6 views
63

Estoy tratando de incorporar ScalaTest a mi proyecto Java, reemplazando todas las pruebas JUnit por ScalaTests. En un punto, quiero verificar si el inyector de Guice inyecta el tipo correcto. En Java, tengo una prueba como esta:Cómo hacer una instancia de comprobación con Scala (Prueba)

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

pero tengo un problema en hacer lo mismo con 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) 
     } 
    } 
} 

It quejas de que el valor instanceof no es miembro de la puerta/ventana/Techo. ¿No puedo usar instanceof de esa manera en Scala?

Respuesta

91

Scala no es Java. Scala simplemente no tiene el operador instanceof sino que tiene un método paramétrico llamado isInstanceOf[Type].

+2

bien, eso realmente no responde la pregunta. ScalaTest tiene soporte integrado para verificación de tipo. Vea la respuesta de @ martin-g – maasg

+3

Mi respuesta es casi 5 años. La técnica 'anInstance mustBe an [SomeClass]' mostrada por @ martin-g no existía en ese momento (como él dice correctamente). Si quería ser técnico al respecto, mi respuesta responde perfectamente a la pregunta del OP, que es: "¿No puedo usar instanceof de esa manera en Scala?". Ambos enfoques funcionan a partir de hoy y, por lo tanto, son ambas respuestas correctas. Tenga un buen día. – agilesteel

+0

¿Cómo hacerlo si "Tipo" es un rasgo? – Lobo

28

Si quiere ser menos parecido a JUnit y si quiere usar los equivalentes de ScalaTest, puede escribir su propio marcador de propiedad que coincida con el tipo (borrado de tipo de barra).

He encontrado este hilo para ser muy útil: http://groups.google.com/group/scalatest-users/browse_thread/thread/52b75133a5c70786/1440504527566dea?#1440504527566dea

entonces usted puede escribir afirmaciones como:

house.door should be (anInstanceOf[WoodenDoor]) 

en lugar de

assert(house.door instanceof WoodenDoor) 
+0

+1 Eso se ve muy bien, e incluso comprensible para personas que no son de programación (suponiendo que sepan qué es una instancia :-)). – helpermethod

+0

Si el azúcar de sintaxis es lo que buscas, con algunas refactorizaciones podrías escribir house.door debería ser (madeOf [Wood]) o house.door debería (madeOf [Bamboo]). –

+1

También vea https://groups.google.com/d/topic/scalatest-users/HeOKgs5PC2o/discussion –

12

las respuestas actuales sobre isInstanceOf [Type] y Los consejos junit son buenos, pero quiero agregar una cosa (para las personas que llegaron a esta página en una capacidad no relacionada con junit). En muchos casos, la coincidencia de patrones scala se ajustará a sus necesidades. Lo recomendaría en esos casos porque te da el encasillado de forma gratuita y deja menos espacio para el error.

Ejemplo:

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

La forma recomendada de probar una coincidencia de patrón en ScalaTest es usar 'inside (foo)' en lugar de 'foo match). Consulte http://www.scalatest.org/user_guide/using_matchers#matchingAPattern –

2

La consolidación de referencia discusión ScalaTest de Guillaume (y otra discusión vinculada a por James Moore) en dos métodos, actualizado para 2.x ScalaTest y Scala 2,10 (para usar ClassTag en lugar de manifiesto):

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

con 2.2.x Scalatest (tal vez incluso antes) se puede utilizar: anInstance mustBe an[SomeClass]

+3

Este es el enfoque recomendado en las versiones recientes de ScalaTests – maasg

+4

también disponible 'a [Type]' para que pueda ser gramaticalmente correcto;) – Samuel

+0

Estaba buscando eso ! :) – Atais

0

utilizo 2.11.8 que ver con la afirmación coll ecciones. La sintaxis más nueva es la siguiente:

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

Debido a la eliminación, no puede verificar los parámetros de tipo del "Mapa". Lo que escribiste es lo mismo que escribir 'scores shouldBe a [Map [_, _]]'. Esto se menciona aquí: http://www.scalatest.org/user_guide/using_matchers#checkingAnObjectsClass –

Cuestiones relacionadas