0

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!

jgmao
  • 147
  • 2
  • 8

1 Answers1

2

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.

assylias
  • 321,522
  • 82
  • 660
  • 783
  • 3
    Simply remove the `MockUp` instead, as it's not needed. In general, you don't mock the class that is being tested. – Rogério Jun 28 '13 at 11:47