Question

I am trying to use JMockit to do behavior test. In one of the test, I need to call a method in the final object. However, the final object is not initialized (null object) and I don't know how to initialize it in the test (since it is defined final). I cannot found the solution to mock a final instance with in a class. See the test first, and I will explain the code.

public class NetworkClientTest {
    @Cascading @Capturing ServerRequestHandler nrh;

    @Test
    public void testRequestSimilar(){
      //define test parameters
      String smiles = "abcd";
      float t = (float) 0.1;
      final Map<String, Object> parameters = new HashMap<String, Object>();
      String smi = StringEscapeUtils.unescapeJava(smiles);
      parameters.put("smiles",smi );
      parameters.put("tanimoto", t);
      //end define test parameters
      //try to initialize NetworkClient object
      new MockUp<NetworkClient>() {
        @Mock
        public void $init(){

        }   
      };
      NetworkClient nc = new NetworkClient();
      new Expectations(){
        //ServerRequestHandler nrh;
        {
            nrh.sendRequest("get_similar_entries", parameters);
        }

    };
    //when nc.requestSimilarEntries is called, nc.nrh.sendRequest will be expected. 
    nc.requestSimilarEntries(smiles, t); 
}

where nrh is a final instance defined in nc (NetworkClient class) and nc.nrh.sendRequest will be called after nc.requestSimilarEntries is called.

public class NetworkClient {
  private final ServerRequestHandler nrh = new ServerRequestHandler();
  ... 
   public void requestSimilarEntries(String smiles, float tanimoto) {
    // Set up parameters
    Map<String, Object> parameters = new HashMap<String, Object>();
    String smi = StringEscapeUtils.unescapeJava(smiles);
    parameters.put("smiles",smi );
    parameters.put("tanimoto", tanimoto);

    // Send a request to the handler
    nrh.sendRequest("get_similar_entries", parameters);
}

The problem is I cannot get the final ServerRequestHandler nrh initialized in the test. The test result says 'missing invocation'. I checked in debug mode (in Eclipse) and nc.nrh is null all the time.

Please let me know if you need more information and thank you for your help!

Was it helpful?

Solution

You are mocking NetworkClient's constructor, which also means that the instance variable are not instantiated. You need to instantiate the nrh variable. For example:

  new MockUp<NetworkClient>() {
    @Mock
    public void $init(Invocation inv){
        NetworkClient client = inv.getInvokedInstance();
        Deencapsulation.setField(client, "nrh", new ServerRequestHandler());
    }   
  };

Now you probably also want to mock the ServerRequestHandler class, in which case you can simply create a new MockUp:

  new MockUp<NetworkClient>() {
  };

  new MockUp<ServerRequestHandler>() {
  };

Note: I have not used jmockit in a while so it might not work but probably worth trying.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top