2012-06-20 20 views
8

El título casi lo dice todo. Me gustaría establecer una prueba JUnit tradicional para simular las dependencias de un controlador y ejecutar pruebas contra acciones.Prueba de unidad a Controlador de juego usando mocks

He descubierto que puedo alcanzar mi meta de esta manera:

public class AccountsControllerTest { 
    private controllers.Accounts accountsController; 

    @Test 
    public void test() { 
     running(fakeApplication(), new Runnable() { 
      public void run() { 
       accountsController = new controllers.Accounts(); 
       accountsController.setAccountsWorkflow(mock(workflow.Accounts.class)); 
      } 
     }); 
    } 
} 

El problema obvio aquí es que estoy crear instancias de mi clase que se está probando y la inyección de dependencias simulacros del método de prueba en sí, cuando debería estar haciendo eso en el método setup(). Parece que el método setup() es inútil si voy a probar mi controlador de forma tradicional.

Por supuesto que puedo probar los controladores the way Play recommends, pero mi aplicación depende de un servicio web SOAP externo, por lo que necesito pruebas unitarias para mostrar que nuestro código funciona cuando los servidores están caídos.

Entonces, ¿cuál es la mejor manera de probar la unidad de un controlador Play utilizando simulaciones mientras se siguen aprovechando los métodos setup() y teardown()?

Editar

Soy consciente de que estoy asumiendo un cierto conocimiento aquí, así que para aquellos que no son conscientes, instanciación controlador en una unidad de prueba debe ser envuelto en una función running() o el juego! arrojará una excepción de tiempo de ejecución diciendo que no se ha iniciado ninguna aplicación.

+0

http://www.joergviola.de/blog/2012/06/04/page-driven-functional-tests-for-play-2-dot-0/ es una buena manera de probar también, pero aún tiene el problema de simulacro. Podría intentar ejecutar la prueba sin la aplicación fake. Consulte http://stackoverflow.com/questions/10381354/how-to-manipulate-session-request-and-response-for-test-in-play2-0 – niels

+0

http://stackoverflow.com/a/10114621/89509 –

+0

Gracias por el ejemplo. ¿Cómo pudiste instanciar el controlador fuera de la función 'running'? Esta restricción es lo que me impide aprovechar el método 'setup' de JUnit, así que no tengo que configurar simulaciones en cada método de prueba. Tu ejemplo realmente no demuestra esto. – Samo

Respuesta

1

Puede lograr esto usando Mockito and Play's FakeApplication y estableciendo la variable estática Http.Context.

De esta forma puede escribir la prueba como todas las demás pruebas JUnit.

Ejemplo:

... 
import static play.test.Helpers.status; 
import play.test.FakeApplication; 
import play.test.Helpers; 
import play.mvc.Http; 
import play.mvc.Result; 
... 

@RunWith(MockitoJUnitRunner.class) 
public class ApplicationTest { 

    public static FakeApplication app; 

    @Mock 
    private Http.Request request; 

    @BeforeClass 
    public static void startApp() { 
     app = Helpers.fakeApplication(); 
     Helpers.start(app); 

    } 

    @Before 
    public void setUp() throws Exception { 
     Map<String, String> flashData = Collections.emptyMap(); 
     Http.Context context = new Http.Context(request, flashData, flashData); 
     Http.Context.current.set(context); 
    } 

    @Test 
    public void testIndex() { 
     final Result result = Application.index(); 
     assertEquals(play.mvc.Http.Status.OK, status(result)); 
    } 

    @AfterClass 
    public static void stopApp() { 
     Helpers.stop(app); 
    } 
+0

No sabía que pudiera establecer el Http.Context actual de esa manera, eso es genial; Gracias. – duma

+0

Encontré que al establecer 'Http.Context.current.set (context);' mis pruebas subsiguientes basadas en la Aplicación fallaron. Por lo tanto, debe establecer el contexto en su estado original en @AfterClass. –