1

How can we test method arguments which have Generics as a method argument.

public class AbstractServiceClient(){
  public constructBusinessClient(String serviceName, String clientName, Class<? extends AbstractTO> requestClass, AbstractTO serviceRequestTO){
    constructBusinessServicesRestClientProperties(servicename, clientName,  requestClass, servicerequestTO);
  }

//write a test case to check if the the class that extends AbstractTO is passed to the below method (Class requestClass)

 public BusinessServicesRestClient constructBusinessServicesRestClientProperties(String serviceName,String  clientName, Class<? extends AbstractTO> requestClass
       , AbstractTO serviceRequestTO){
      //set values
    }
  }

   public class AbstractServiceClientTest {

    private Class<? extends AbstractTO> requestClass;  
    private static final String CLIENT_NAME = "clientName";
    private  AbstractTO serviceRequestTO ;
    private AbstractServiceClient abstractServiceClient;

 @Test
public void constructBusinessServiceClientShouldSetCorrectClientName() {
abstractServiceClient.constructBusinessClient(operation,clientName, requestClass,  abstractClass);          
abstractServiceClient.constructBusinessServicesRestClientProperties(any(String.class), eq(CLIENT_NAME), requestClass, any(AbstractTO.class));
    }   
  }
 @Test
 public void constructBusinessServiceClientShouldSetCorrectRequestClass() {
abstractServiceClient.constructBusinessClient(operation,clientName, requestClass,  abstractClass);          
abstractServiceClient.constructBusinessServicesRestClientProperties(any(String.class), eq(CLIENT_NAME), eq(requestClass), any(AbstractTO.class));
    }   
  }
}
user679526
  • 845
  • 4
  • 16
  • 39

1 Answers1

0

This question is a bit too vague to be able to produce code as an answer, but essentially, if the problem is to ensure that method A of class B is called, with certain parameters, when you call method C of class D, then the usual thing to do is the following.

  1. Create a mock object of class B, that you're going to check the interaction on.
  2. Create a real object of class D, that you're actually going to test.
  3. Somehow inject your mock B into your real object D. This may be done via the constructor of D, in which case this step will be part of step 2.
  4. Call method C, passing whatever arguments are required.
  5. Verify that method A was called, with the right arguments on your mock object.

If the return value of method A is important for the workings of class D, then it will work like this instead.

  1. Create a mock object of class B, that you're going to check the interaction on.
  2. Create a real object of class D, that you're actually going to test.
  3. Somehow inject your mock B into your real object D. This may be done via the constructor of D, in which case this step will be part of step 2.
  4. Stub method A, so that when it's called with the correct arguments, the appropriate return value is returned.
  5. Call method C, passing whatever arguments are required.
  6. Check the state of your object of class D, to ensure that the return value from A has had the correct effect on the state. If the state of D is not correct, then either D is not handling the return correctly, or method A was never called, or method A was called with the wrong arguments.

In this second case, there is no need to verify the mock as well as stubbing it. The mocking purists will tell you that you should either stub, or verify, but never both.

Now, looking at the code in your question, it doesn't seem to me that you've done any of the required steps. So this "test case" is not going to do anything much. Even if you think "it works", you haven't tested anything.

As far as the use of Mockito is concerned, you would use a method call with matchers EITHER to stub a method, OR to verify it; so your code could be used in either of the two scenarios I've described above.

But you have to do one or the other. So if you're verifying, you might write

verify(mockAbstractServiceClient).constructBusinessServicesRestClientProperties(anyString(), eq(CLIENT_NAME), eq(SomeConcreteTO.class), any(AbstractTO.class));

or if you're stubbing, you might write

doReturn(someValue).when(mockAbstractServiceClient).constructBusinessServicesRestClientProperties( anyString(), eq(CLIENT_NAME), eq(SomeConcreteTO.class), any(AbstractTO.class));

There is another way of writing this, of course, using when and thenReturn, but I find it more intuitive to use doReturn instead.

Note that in both of these, I've used eq around a Class object. This is how to check that that is the class that's getting passed in to the method.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110