Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a jUnit test for a class that uses a network connection

I would like to know what's the best approach to test the method "pushEvent()" in the following class with a jUnit test. My problem is, that the private method "callWebsite()" always requires a connection to the network. How can I avoid this requirement or refactor my class that I can test it without a connection to the network?

class MyClass {      public String pushEvent (Event event) {         //do something here         String url = constructURL (event); //construct the website url         String response = callWebsite (url);          return response;     }      private String callWebsite (String url) {         try {             URL requestURL = new URL (url);             HttpURLConnection connection = null;             connection = (HttpURLConnection) requestURL.openConnection ();               String responseMessage = responseParser.getResponseMessage (connection);             return responseMessage;         } catch (MalformedURLException e) {             e.printStackTrace ();             return e.getMessage ();         } catch (IOException e) {             e.printStackTrace ();             return e.getMessage ();         }     }  } 
like image 418
flash Avatar asked Apr 27 '10 18:04

flash


People also ask

How do you write JUnit test cases for model classes in Java?

@RunWith(MockitoJUnitRunner. class) public class MyClassTest{ @InjectMocks MyClass myClass; @Mock MyDAO myDAO; private MyObject myObj; private List<MyObject> objList; @Before public void setUp() throws Exception { myObj = new MyObject(); myObj.

Can we use data provider in JUnit?

Apparently JUnit does not provide support for data providers, which makes it rather annoying to test the same method with 20 different versions of an argument.


1 Answers

Stubbing

You'll need a test double (stub) to allow isolated, easy, unit testing. The following is non tested, but demonstrates the idea. The use of Dependency Injection will allow you to inject at test time, a test version of your HttpURLConnection.

public class MyClass()  {    private IHttpURLConnection httpUrlConnection;        public MyClass(IHttpURLConnection httpUrlConnection)    {        this.httpUrlConnection = httpUrlConnection;    }     public String pushEvent(Event event)     {        String url = constructURL(event);        String response = callWebsite(url);        return response;   } } 

Then you create a stub (sometimes referred to as a mock object) to be the stand in for the concrete instance.

class TestHttpURLConnection : IHttpURLConnection { /* Methods */ } 

You'll also construct a concrete version, for your production code to use.

class MyHttpURLConnection : IHttpURLConnection { /* Methods */ } 

Using your test class (an adapter) you are able to specifiy what should happen during your test. A mocking framework will enable you to do this with less code, or you can manually wire this up. The end result of this for your test is that you'll set your expectations for your test, for example, in this case you may set OpenConnection to return a true boolean (This is just an example by the way). Your test will then assert that when this value is true, the return value of your PushEvent method matches some expected result. I've not touched Java properly for a while, but here are some recommended mocking frameworks as specified by StackOverflow members.

like image 141
Finglas Avatar answered Sep 30 '22 13:09

Finglas