I have made a small "webserver" as a mock for my JUnit tests. this is the code of the "webserver":

while(true) {

    try {
        ServerSocket socket = new ServerSocket(port);
        socket.setReuseAddress(true);
        Socket remote = s.accept();
        PrintWriter out = new PrintWriter(remote.getOutputStream(), true);
        out.append("some data");
        out.flush();
        out.close();    
        remote.close(); 
        socket.close();
    }
    catch (IOException e) { 
        throw new RuntimeException(e);
    }

and this is what i am doing in the code of the program:

    URL url = new URL(urlstr);  
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.connect();
    MyClass myClass = (MyClass) unmarshaller.unmarshal(con.getInputStream());
    con.disconnect();
    return myClass;

here my problem: sometimes it works, sometimes not. and i don't know why. i get this error:

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:180)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:230)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:270)
at java.io.BufferedInputStream.read(BufferedInputStream.java:329)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:688)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:653)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1067)
at my.program.Program.myMethod(...)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:600)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.junit.runners.Suite.runChild(Suite.java:115)
at org.junit.runners.Suite.runChild(Suite.java:23)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

why it's working sometimes? and why sometimes not? what is wrong? i have to run my junit test 5 or 10 times to get it work one time.

link|improve this question

What exactly are you trying to test here? The socket connection to a web server? Or the unmarshaling of the stream? Have you thought about breaking that chunk of code into separate more easily testable classes? – jkeeler Oct 14 '11 at 19:53
i want to test the unmarshalling of the stream. i return a XML string and I want to see whether my program handles it correct or not. Normally, my program gets this XML file from a real server and I want to create a mock for this server. A very simple one, that just returns a XML string (the same for every request). – Thomas Uhrig Oct 14 '11 at 19:59
feedback

2 Answers

up vote 2 down vote accepted

An indirect answer: don't try to do it yourself. Use an embedded Simple or Jetty server. With roughly the same amount of code, you'll get a relatively huge amount of functionality beyond what you have, and you won't encounter strange problems like this, either.

The "connection reset" is happening because you're closing the socket before the url connection is ready for you to do so.

link|improve this answer
alright, jetty works great. i thought it would be more complicated to set up a real webserver but that was very easy. thanx. – Thomas Uhrig Oct 14 '11 at 22:25
feedback

The code block you've posted performs both the HTTP connection and the unmarshalling of the response. Unit testing works best when there is good separation of concerns. That means create separate classes for the connection and the unmarshalling logic. Once you've done this, you can test just the unmarshalling with code like this:

class Unmarshaller {
  public MyClass unmarshal(InputStream is) {
    return (MyClass) unmarshaller.unmarsal(is);
  }
}

class UnmarshallerTests {
  @Test
  public void testUnmarshal() {
    Unmarshaller u = new Unmarshaller();
    FileInputStream fis = new FileInputStream("test-sample.xml");
    u.unmarshal(fis);
}

You can now test your unmarshaller with any type of InputStream. In this case, I've used a sample XML file from disk.

link|improve this answer
good tip. but i think i will need the webserver, too. the program use it for different functions and a mock would be great. – Thomas Uhrig Oct 14 '11 at 22:27
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.