0

I have a function, which calls an ElasticSearch function:

List<Long> docItems = docFieldLongs(docItemField).getValues();

It then does some calculation and output based on docItems.

The issue is in testing, I do not create a big mock elasticsearch node and such. Instead I want to create an override of this function, to be called in testing.

The question is how do I do this? This new function should be called in the test rather than the Elasticsearch function. I wanted to do something like below, but this doesn't work due to Unknown macro not being available. Else I can create ScriptDocValues.Longs although can't seem to find how to do this!

@Override
private ScriptDocValues.Longs docFieldLongs(String getter){

    List<Long> docFields =  new ArrayList<Long>();
    docFields.add(new Long(101));
    docFields.add(new Long(102));

    Unknown macro: return docFields;
}

My two questions are as follows:

  • How to override a function for test purposes only?
  • How to imitate the docFieldLongs?

EDIT - note this is NOT a solution, just along the lines to one:

I have been working on this for a while, seems very long winded. Here is a rough solution, so far:

    @Test
public void testRunAsLongs()
{
    script = new MaxiScoreScript(params){
        @Override
        public ScriptDocValues.Longs docFieldLongs(String getter)
        {
            try{
                writer = new IndexWriter(new RAMDirectory(), new IndexWriterConfig(Lucene.VERSION, new StandardAnalyzer(Lucene.VERSION)).setMergePolicy(new LogByteSizeMergePolicy()));
            }
            catch(IOException e){

            }
            Document d  = new Document();
            d.add(new LongField("value", 102, Field.Store.NO));
            d.add(new LongField("value" ,101, Field.Store.NO));
            try{
                writer.addDocument(d);
            }
            catch(IOException e){

            }
            IndexNumericFieldData indexFieldData = null;
            try {
                indexFieldData = IndexFieldDataService.getForField("value");
            }
            catch(IOException e){
                System.out.println("getting field data failed");
            }
            AtomicNumericFieldData fieldData = null;
            try{
                fieldData = indexFieldData.load(refreshReader());
            }
            catch(Exception e)
            {

            }
            return (ScriptDocValues.Longs) fieldData.getScriptValues();
        }

    }

}

If you are interested in seeing the behaviour of docFieldLongs also you may wish to look into Longs

redrubia
  • 2,256
  • 6
  • 33
  • 47
  • I think you want to use a mock library for unit testing your code. Have a look at [Mockito](http://code.google.com/p/mockito/) – mconlin Mar 13 '14 at 11:06
  • Thanks for your response @mconlin but I don't feel mockito will work in this case, unless I can create override mock functions to then test the main function. I think I need more of the lines http://stackoverflow.com/questions/1069152/when-to-use-override-in-java – redrubia Mar 13 '14 at 12:12

1 Answers1

0

If I understand what you are trying to do, I think you want something like this:

public class JaccardScoreScript {
    Map<String, ScriptDocValues.Longs> mydocs = new HashMap<>();
    private Map<String, ScriptDocValues.Longs> doc() {
        return mydocs;
    }
    protected ScriptDocValues.Longs docFieldLongs(String field) {
        return doc().get(field);
    }
}

If you want to override the docFieldLongs method, you need to extend the class:

public class MockJaccardScoreScript extends JaccardScoreScript {
    @Override
    protected ScriptDocValues.Longs docFieldLongs(String field) {
        ScriptDocValues.Longs longs = /*construct your test data object here*/;
        return longs;
    }
    public static void main(String[] args) {
        JaccardScoreScript script = new MockJaccardScoreScript();
        System.out.println("docFieldLongs: " + script.docFieldLongs("anything"));
    }
}
climmunk
  • 1,141
  • 1
  • 12
  • 29
  • yes that is partically correct. But it doesn't return a List, it returns ScriptDocValues.Longs which is a class in Elasticsearch. Using this, it says 'attempting to use incompatible type return' – redrubia Mar 13 '14 at 14:39
  • I tried to simplify the code example by using Long, but I'll edit it to use your specific data type. – climmunk Mar 13 '14 at 15:17
  • Thanks, this is great. The difficulty I've been having is how to create the ScriptDocValues.Longs -> not very easy with ES. – redrubia Mar 13 '14 at 15:26
  • How is it typically created? From a web response? Perhaps you can just create a file which contains a typical response and hard code the values you want. – climmunk Mar 13 '14 at 15:40
  • still having problems. Mockito doesn't work, as the class is protected. Override doesn't either as it returns a ScriptDocValues, not a list and creating ScriptDocValues seems impossible, as my function shows -> very complex and still fails. – redrubia Mar 13 '14 at 19:06