2011-06-08 17 views
13

que necesito para llenar mis pruebas ScalaTest con @Autowired campos de un contexto de primavera, pero la mayoría de las pruebas Scalatest (por ejemplo FeatureSpec s no se puede ejecutar por el SpringJUnit4ClassRunner.class -¿Cómo se integra con Spring ScalaTest

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations="myPackage.UnitTestSpringConfiguration", loader=AnnotationConfigContextLoader.class) 
public class AdminLoginTest { 
    @Autowired private WebApplication app; 
    @Autowired private SiteDAO siteDAO; 

(java, pero se obtiene la esencia).

¿Cómo pueblan @Autowired campos de un ApplicationContext para ScalaTest?

class AdminLoginFeatureTest extends FeatureSpec with GivenWhenThen with ShouldMatchersForJUnit { 

    @Autowired val app: WebApplication = null 
    @Autowired val siteDAO: SiteDAO = null 

    feature("Admin Login") { 
    scenario("Correct username and password") {...} 

Respuesta

26

Utilice TestContextManager, ya que guarda en caché los contextos para que no se reconstruyan todas las pruebas. Se configura a partir de las anotaciones de clase.

@ContextConfiguration(
    locations = Array("myPackage.UnitTestSpringConfiguration"), 
    loader = classOf[AnnotationConfigContextLoader]) 
class AdminLoginFeatureTest extends FeatureSpec with GivenWhenThen with ShouldMatchers { 

    @Autowired val app: WebApplication = null 
    @Autowired val siteDAO: SiteDAO = null 
    new TestContextManager(this.getClass()).prepareTestInstance(this) 

    feature("Admin Login") { 
    scenario("Correct username and password") {...} 
    } 
} 
3

He intentado utilizar la respuesta de Duncan con Spring 4 + Scala 2.11 y me dieron el siguiente error:

java.lang.IllegalStateException: Test class [TestGateway] has been configured with @ContextConfiguration's 'locations' (or 'value') attribute {GatewayContextConfiguration}, but AnnotationConfigContextLoader does not support resource locations. 

que tenía que ajustar su código para utilizar una clase en la configuración del ContextConfiguration lugar de una cadena :

@ContextConfiguration(classes = Array(classOf[GatewayContextConfiguration]), 
         loader = classOf[AnnotationConfigContextLoader]) 
class TestGateway extends FlatSpec with Matchers { 

    @Autowired val gpClient: IGlobalPropsWSClient = null 

    new TestContextManager(this.getClass()).prepareTestInstance(this) 

    "Echo" should "return what it was sent." in { 
    val gateway = new CasaWsGateway 
    gateway.echo("This is a test") should be ("This is a test") 
    } 
} 
3

Aquí hay una versión implementado como un rasgo apilable (de modo que usted puede tener sus propias beforeAll() y afterAll() métodos, si es necesario) que usa TestContextManager para completar el ciclo de vida del contexto.

Probé la solución cruda TestContextManager.prepareTestInstance() sugerido en otras críticas, pero me di cuenta de que mis contextos no se estaban cerrados que da lugar a efectos secundarios y la acumulación de basura después de cada prueba sucesiva cuando se utiliza la consola de SBT.

@ContextConfiguration(classes = Array(classOf[SomeConfiguration])) 
class SomeTestSpec extends FlatSpec with TestContextManagement { 

    // Use standard Autowired Spring annotation to inject necessary dependencies 
    // Note that Spring will inject val (read-only) fields 
    @Autowired 
    val someDependency: SomeClass = null 

    "Some test" should "verify something" in { 
    // Test implementation that uses injected dependency 
    } 

} 

TestContextManagement Gist

import org.scalatest.{BeforeAndAfterAll, Suite} 
import org.springframework.core.annotation.{AnnotatedElementUtils, AnnotationAttributes} 
import org.springframework.test.annotation.DirtiesContext 
import org.springframework.test.context.{TestContext, TestContextManager} 
import org.springframework.test.context.support.DirtiesContextTestExecutionListener 
import org.springframework.util.Assert 

/** 
* Manages Spring test contexts via a TestContextManager. 
* 
* Implemented as a stackable trait that uses beforeAll() and afterAll() hooks to invoke initialization 
* and destruction logic, respectively. 
* Test contexts are marked dirty, and hence cleaned up, after all test methods have executed. 
* There is currently no support for indicating that a test method dirties a context. 
* 
* @see org.springframework.test.context.TestContextManager 
*/ 
trait TestContextManagement extends BeforeAndAfterAll { this: Suite => 

    private val testContextManager: TestContextManager = new TestContextManager(this.getClass) 

    abstract override def beforeAll(): Unit = { 
    super.beforeAll 
    testContextManager.registerTestExecutionListeners(AlwaysDirtiesContextTestExecutionListener) 
    testContextManager.beforeTestClass 
    testContextManager.prepareTestInstance(this) 
    } 

    abstract override def afterAll(): Unit = { 
    testContextManager.afterTestClass 
    super.afterAll 
    } 
} 

/** 
* Test execution listener that always dirties the context to ensure that contexts get cleaned after test execution. 
* 
* Note that this class dirties the context after all test methods have run. 
*/ 
protected object AlwaysDirtiesContextTestExecutionListener extends DirtiesContextTestExecutionListener { 

    @throws(classOf[Exception]) 
    override def afterTestClass(testContext: TestContext) { 
    val testClass: Class[_] = testContext.getTestClass 
    Assert.notNull(testClass, "The test class of the supplied TestContext must not be null") 

    val annotationType: String = classOf[DirtiesContext].getName 
    val annAttrs: AnnotationAttributes = AnnotatedElementUtils.getAnnotationAttributes(testClass, annotationType) 
    val hierarchyMode: DirtiesContext.HierarchyMode = if ((annAttrs == null)) null else annAttrs.getEnum[DirtiesContext.HierarchyMode]("hierarchyMode") 
    dirtyContext(testContext, hierarchyMode) 
    } 
} 
0

Si está utilizando arranque primavera se podría utilizar el TestContextManager (como otros comentarios sugirieron) y la anotación @SpringBootTest.

Éste es cómo probar un controlador con scalaTest y la primavera de arranque:

@RunWith(classOf[SpringRunner]) 
@SpringBootTest(webEnvironment = RANDOM_PORT) 
class CustomerControllerIT extends FeatureSpec with GivenWhenThen with Matchers { 

    @Autowired 
    var testRestTemplate: TestRestTemplate = _ 
    new TestContextManager(this.getClass).prepareTestInstance(this) 

    @LocalServerPort 
    val randomServerPort: Integer = null 

    val baseUrl = s"http://localhost:$randomServerPort" 

    feature("Customer controller") { 

    scenario("Find customer by id") { 

     Given("a customer id") 
     val id = 1 

     When("a request to /customers/{id} is sent") 
     val url = s"$baseUrl/customers/$id" 
     val response = testRestTemplate.getForEntity(url, classOf[Customer]) 

     Then("we get a response with the customer in the body") 
     response.getBody.getId shouldBe 1 
     response.getBody.getName shouldBe "Bob" 

    } 

    } 

} 

Aquí hay un post acerca de cómo hacer las pruebas de integración y pruebas de unidad con arranque primavera y ScalaTest: ignaciosuay.com/testing-spring-boot-with-scalatest/

Cuestiones relacionadas