2015-09-25 17 views
5

Dopo aver lavorato quasi tutto il giorno, mi sento come se fossi abbastanza vicino a una soluzione su come testare un metodo controller che accetta i caricamenti di file da JUnit. Il mio codice di prova juint è la seguente:Caricamento del file di test delle unità in un controller con Java Play Framework 2.3.x

Map<String, String> postData = makePostMap(uploadForm); 
File file = new File("test/resources/shared/uploads/blank.csv"); 
TemporaryFile temporaryFile = new TemporaryFile(file); 

MultipartFormData.FilePart filePath = new MultipartFormData.FilePart(
     "file", 
     "file.csv", 
     new scala.Some<>("text/csv"), 
     temporaryFile); 

List<MultipartFormData.FilePart> fileParts = Lists.newArrayList(filePath); 
scala.collection.immutable.Seq files = JavaConversions.asScalaBuffer(fileParts).toList(); 

Map<String, scala.collection.immutable.Seq<String>> postData2 = new HashMap<>(); 
for (String s : postData.keySet()) { 
    postData2.put(s, JavaConversions.asScalaBuffer(Lists.newArrayList(postData.get(s))).toList()); 
} 
scala.collection.immutable.Map<String, scala.collection.immutable.Seq<String>> scalaMap = 
     JavaConversions.mapAsScalaMap(postData2).toMap(Predef.<Tuple2<String, scala.collection.immutable.Seq<String>>>conforms()); 

MultipartFormData formData = new MultipartFormData(scalaMap, files, null, null); 
AnyContentAsMultipartFormData body = new AnyContentAsMultipartFormData(formData); 

// run 
login(employee); 
String url = routes.ManageContacts.uploadCsv().url(); 
FakeRequest fakeRequest = new FakeRequest(POST, url).withBody(body); 
fakeRequest = getAuthenticatedRequest(fakeRequest, employee); 

result = route(fakeRequest); 

assertThat(status(result)).isEqualTo(OK) 

Tuttavia, ottengo un'eccezione (sotto) quando il FakeRequest viene instradato.

[error] Test controllers.ManageContactsTest.testUploadCsv failed: scala.MatchError: AnyContentAsMultipartFormData(MultipartFormData(Map(clearExisting -> List(false), survey -> List(11), bosMode -> List(false)),List(FilePart(file,file.csv,Some(text/csv),TemporaryFile(test/resources/shared/uploads/blank.csv))),null,null)) (of class play.api.mvc.AnyContentAsMultipartFormData), took 0.255 sec 
[error]  at play.api.test.RouteInvokers$class.jRoute(Helpers.scala:255) 
[error]  at play.api.test.Helpers$.jRoute(Helpers.scala:403) 
[error]  at play.api.test.Helpers.jRoute(Helpers.scala) 
[error]  at play.test.Helpers.route(Helpers.java:445) 
[error]  at play.test.Helpers.route(Helpers.java:437) 
[error]  at play.test.Helpers.route(Helpers.java:433) 
[error]  at controllers.ManageContactsTest.testUploadCsv(ManageContactsTest.java:121) 
[error]  ... 

Diving giù nella traccia dello stack, trovo la seguente dichiarazione scala partita nel file: /Users/jcreason/bin/playframework-2.3.8/framework/src/play-test/src/main/scala/play/api/test/Helpers.scala:253

def jRoute[T](app: Application, r: FakeRequest[T]): Option[Future[Result]] = { 
    (r.body: @unchecked) match { 
     case body: AnyContentAsFormUrlEncoded => route(app, r, body) 
     case body: AnyContentAsJson => route(app, r, body) 
     case body: AnyContentAsXml => route(app, r, body) 
     case body: AnyContentAsText => route(app, r, body) 
     case body: AnyContentAsRaw => route(app, r, body) 
     case body: AnyContentAsEmpty.type => route(app, r, body) 
     //case _ => MatchError is thrown 
    } 
    } 

Dal momento che sto passando attraverso AnyContentAsMultipartFormData, si genera questa eccezione come non è gestita dalla partita. Qualcuno sa come aggirare questo? O potrebbe indicarmi la direzione di una diversa soluzione a questo (oltre alle risposte ovvie proprio come il selenio)?

Per avere un riferimento, ho tirato un po 'di questo codice:

http://www.erol.si/2014/02/how-to-test-file-uploads-in-play-framework-java/

+0

Ciao, sono l'autore dell'articolo. Ho provato questo con Play 2.2 ma sembra che poche cose siano cambiate. Lo testerò con la versione più recente, ma nel frattempo è possibile controllare l'esempio in scala https://github.com/playframework/playframework/blob/9f258fcd248ea79ad38f0fddfe4192a2ccf4afb0/documentation/manual/working/scalaGuide/main/upload/code/ScalaFileUpload. scala – FrEaKmAn

+0

Come si sta usando Java, forse sarà utile osservare questo: https://github.com/playframework/playframework/blob/9f258fcd248ea79ad38f0fddfe4192a2ccf4afb0/documentation/manual/working/javaGuide/main/upload/code/JavaFileUpload.java – Anton

+0

Grazie per la risposta @FrEaKmAn, proverò a controllare la versione di Scala quando avrò un momento libero, grazie. – jcreason

risposta

0

Questo codice può essere utile:

import static play.test.Helpers.*; 
import static org.junit.Assert.*; 
import java.util.*; 
import org.junit.Test; 
import akka.stream.javadsl.Source; 
import akka.util.ByteString; 
import play.mvc.Http.MultipartFormData.*; 
import play.mvc.Http.RequestBuilder; 
import play.mvc.Result; 
import play.test.*; 

class UploadFileTest extends WithApplication { 
    @Test 
    public void uploadTest() { 
     Part<Source<ByteString, ?>> part = new FilePart<>("key", "fileName", "application/octet-stream", 
       Source.empty()); 
     List<Part<Source<ByteString, ?>>> data = Arrays.asList(part); 

     RequestBuilder requestBuilder = fakeRequest(controllers.routes.UploadController.upload()).method(POST) 
       .bodyMultipart(data, mat); 

     Result result = route(app, requestBuilder); 

     assertEquals(Helpers.OK, result.status()); 
    } 
} 

Se si desidera inviare file non vuoto,
invece di Source.empty() utilizzare FileIO.fromFile(new File("path/to/file"));

Problemi correlati