Mockito UnfinishedStubbingException

前端 未结 4 1306
离开以前
离开以前 2020-12-09 08:49

I am new to Mockito, I have tried looking into this Exception but I haven´t found a concrete answer. It happens in my code when I use two mocks together, meaning that I give

相关标签:
4条回答
  • 2020-12-09 09:31

    There are some good fixes posted in this question already, but for anyone still having trouble understanding it, think of the order in which Java calls all those methods. According to the Java Language Specification, Java evaluates every parameter of a method left-to-right before calling the method:

    1. integerValue.getValue(), which Mockito records
    2. when, where Mockito takes the last call (to integer.getValue) and starts setting up stubbing
    3. value.toString, which is a mocked call that Mockito records
    4. thenReturn on the stubber

    Mockito complains exactly because the call to the mock, step 3, happens after step 2 (when) but before step 4 (thenReturn), causing the validation framework to complain about the stubbing. Joy, your answer moves the troublesome step 3 to before step 1, which is fine; Sajan removes it from the statement entirely, which is also fine.

    0 讨论(0)
  • I think the problem is with line

    Mockito.when(node.toString()).thenReturn(value.toString()); in method getConstantNode

    Try removing the line and check if it works. May be you can do something like

    int num = 2;
    child.insertNode(getConstantNode(getIntegerValue(num), num);
    ...
    
     private ConstantNode getConstantNode(NumericalValue value){
        ConstantNode node = Mockito.mock(ConstantNode.class);
        Mockito.when(node.evaluate()).thenReturn(value);
        Mockito.when(node.toString()).thenReturn(Integer.toString(number));
        return node;
    }
    
    private IntegerValue getIntegerValue(int number) {
       IntegerValue integerValue = Mockito.mock(IntegerValue.class);
       Mockito.when(integerValue.getValue()).thenReturn(number);
       return integerValue;
    }
    
    0 讨论(0)
  • 2020-12-09 09:34

    I think this is an issue with the ordering of the calls and Mockito Framework validation. Try this and see if it helps:

    ...
    OperationNode child = getNode(Operation.ADD);
    IntegerValue value = getIntegerValue(2);
    ConstantNode node =  Mockito.mock(ConstantNode.class);
    Mockito.when(node.evaluate()).thenReturn(value);
    Mockito.when(node.toString()).thenReturn(value.toString());
    child.insertNode(node);
    
    ...
    
    private IntegerValue getIntegerValue(int number) {
       IntegerValue integerValue = Mockito.mock(IntegerValue.class);
       Mockito.when(integerValue.getValue()).thenReturn(number);
       Mockito.when(integerValue.toString()).thenReturn(Integer.toString(number));
       return integerValue;
    }
    

    Source: https://code.google.com/p/mockito/issues/detail?id=53

    0 讨论(0)
  • 2020-12-09 09:45

    From what I read on "Issue 53" of mockito (https://code.google.com/p/mockito/issues/detail?id=53) , my code was experiencing a problem due to the validation framework involved in Mockito. Precisely the following code was causing the exception per se.

    private ConstantNode getConstantNode(NumericalValue value){
        ConstantNode node = Mockito.mock(ConstantNode.class);
        Mockito.when(node.evaluate()).thenReturn(value);
        Mockito.when(node.toString()).thenReturn(value.toString());
        return node;
    }
    

    If you remember from my code, the parameter value is ALSO A MOCK, so that when value.toString() is called on the thenReturn(), I believe (and someone please correct me if I am wrong) that the validation framework is triggered and makes sure that every "when" has had its thenReturn() called/validated/etc. So that if this happenes, the Mockito.when(node.toString()).thenReturn(value.toString() will not be validated because it hasn´t returned from the valute.toString(), which started the whole "validate everything" chain.

    How I fixed it:

    private ConstantNode getConstantNode(NumericalValue value){
        ConstantNode node = Mockito.mock(ConstantNode.class);
        Mockito.when(node.evaluate()).thenReturn(value);
    
        String numberToString = value.toString();
    
        Mockito.when(node.toString()).thenReturn(numberToString);
        return node;
    }
    

    This way, it can be validated. I find this a complete code smell because I will literally have to leave a comment that explains why I am using a seemingly useless intermediate variable in the code.

    Thanks for the help.

    0 讨论(0)
提交回复
热议问题