2012-06-20 4 views
8

Il titolo dice quasi tutto. Vorrei creare un tradizionale test JUnit per deridere le dipendenze di un controller ed eseguire test contro le azioni.Unità testare un controller di gioco usando i mazzi

ho trovato che posso raggiungere il mio obiettivo in questo modo:

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

Il problema evidente è che sto istanziare la mia classe in prova e l'iniezione di dipendenze finto dal metodo di prova stessa, quando ho dovrebbe farlo nel metodo setup(). Sembra che il metodo setup() sia inutile se sto andando a testare il mio controller in modo tradizionale.

Naturalmente posso testare i controller the way Play recommends, ma la mia domanda è dipendente da un servizio SOAP Web esterno, quindi ho bisogno di unit test per dimostrare che il nostro codice funziona quando i loro server sono giù.

Quindi, qual è il modo migliore per testare un controller di gioco usando i simulatori sfruttando ancora i metodi setup() e teardown()?

Modifica

mi rendo conto che sto assumendo una certa conoscenza qui, quindi per coloro che non sono a conoscenza, il controllore di un'istanza in una prova di unità deve essere avvolto in una funzione running() o giocare! genererà un'eccezione di runtime dicendo che nessuna applicazione è stata avviata.

+0

http://www.joergviola.de/blog/2012/06/04/page-driven-functional-tests-for-play-2-dot-0/ è un buon modo per testare, ma ha ancora il problema finto. Potresti provare a eseguire il test senza FakeApplication. Vedi 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

Grazie per l'esempio. Come sei riuscito a creare un'istanza del controller al di fuori della funzione 'running'? Questo vincolo è ciò che mi impedisce di sfruttare il metodo 'setup' di JUnit, quindi non devo impostare mock su ogni metodo di test. Il tuo esempio in realtà non lo dimostra. – Samo

risposta

1

È possibile eseguire questa operazione utilizzando Mockito e Play's FakeApplication e impostando la variabile statica Http.Context.

In questo modo è possibile scrivere il test come tutti gli altri test JUnit.

Esempio:

... 
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

Non sapevo che si potesse impostare l'attuale Http.Context in quel modo: è bello; Grazie. – duma

+0

L'ho trovato impostando 'Http.Context.current.set (context);' i miei test successivi basati sull'applicazione non sono riusciti. Quindi devi riportare il contesto allo stato originale in un @AfterClass. –