How to verify the following case in JUNIT / Mockito

 public void doFoo(int x, int y, String url) {
    JSONObject json = new JSONObject().put("z", x + y);
     try (final HttpUtility httpUtils = new HttpUtility()) {
          httpUtils.doAuthPutJson(url,json);
      }
}

I want to verify that input to HTTPUtlity. How do I write unit tests for this ?

1 answer

  • answered 2018-01-11 21:33 davidxxx

    Actually the current class and HttpUtility are strongly coupled in the method.
    If you consider that HttpUtility is a dependency that you want to be able to mock, you have to use it in a way that allows to set the dependency.

    But as actually you have no way to naturally set the HttpUtility dependency in the current class, you think that PowerMockito will solve your issue.
    But in fact it will not.
    It will just hide the design issue.

    With just some little changes, you can have a more clear design and mock HTTPUtlity instantiation in a natural and straight way.

    To achieve it, I would extract the HttpUtility instantiation as a processing performed by a dependency.

    I could so get a code such as :

    public class Foo{
    
       private Supplier<HttpUtility> httpUtilitySupplier;
    
       public Foo(Supplier<HttpUtility> httpUtilitySupplier){
          this.httpUtilitySupplier = httpUtilitySupplier;
       }
    
       public void doFoo(int x, int y, String url) {
         JSONObject json = new JSONObject().put("z", x + y);
         try (final HttpUtility httpUtils = httpUtilitySupplier.get()) {
              httpUtils.doAuthPutJson(url,json);
          }
       }
    }
    

    Note that I use a constructor to set the dependency as it allows to set an invariant about it but if required a setter could be also used.

    Now you can easily check that HttpUtility.doAuthPutJson() is invoked with the expected arguments in your test :

    @RunWith(MockitoJUnitRunner.class)
    public class FooTest {
    
        @Mock
        private HttpUtility httpUtilityMock;
    
        @Test
        public void testName() throws Exception {
            // fixture
            Foo foo = new Foo( () -> httpUtilityMock);
            int x = ...;
            int y = ...;
            String url = ...;
    
            // action
            foo.doFoo(x, y, url);
    
            // assertion
            JSONObject expectedJSONObject = ...;
            Mockito.verify(httpUtilityMock).doAuthPutJson(url, expectedJSONObject);
        }
    }