org.mockito.runners
Class ConsoleSpammingMockitoJUnitRunner

java.lang.Object
  extended by org.junit.runner.Runner
      extended by org.mockito.runners.ConsoleSpammingMockitoJUnitRunner
All Implemented Interfaces:
org.junit.runner.Describable, org.junit.runner.manipulation.Filterable

public class ConsoleSpammingMockitoJUnitRunner
extends org.junit.runner.Runner
implements org.junit.runner.manipulation.Filterable

Uses JUnit 4.5 runner BlockJUnit4ClassRunner.

Experimental implementation that suppose to improve tdd/testing experience. Don't hesitate to send feedback to [email protected] It is very likely it will change in the next version!

This runner does exactly what MockitoJUnitRunner does but also prints warnings that might be useful. The point is that Mockito should help the tdd developer to quickly figure out if the test fails for the right reason. Then the developer can implement the functionality. Also when the test fails it should be easy to figure out why the test fails.

Sometimes when the test fails, the underlying reason is that stubbed method was called with wrong arguments. Sometimes it fails because one forgets to stub a method or forgets to call a stubbed method. All above problems are not immediately obvious.

One way of approaching this problem is full-blown 'expect' API. However it means the 'expectations upfront' business which is not in line with core Mockito concepts. After all, the essence of testing are explicit assertions that are described consistently at the bottom of the test method.

Here's the experiment: a warning is printed to the standard output if the test fails. Also, you get a clickabe link to the line of code. You can immediately jump to the place in code where the potential problem is.

Let's say your test fails on assertion. Let's say the underlying reason is a stubbed method that was called with different arguments:

 //test:
 Dictionary dictionary = new Dictionary(translator);
 when(translator.translate("Mockito")).thenReturn("cool framework");
 String translated = dictionary.search("Mockito");
 assertEquals("cool framework", translated);
 
 //code:
 public String search(String word) {
     ...
     return translator.translate("oups");

 
On standard output you'll see something like that:
 [Mockito] Warning - stubbed method called with different arguments.
 Stubbed this way:
 translator.translate("Mockito");
 org.dictionary.SmartDictionaryTest.shouldFindTranslation(SmartDictionaryTest.java:27)
  
 But called with different arguments:
 translator.translate("oups");
 org.dictionary.SmartDictionary.search(SmartDictionary.java:15)
 

Note that it is just a warning, not an assertion. The test fails on assertion because it's the assertion's duty to document what the test stands for and what behavior it proves. Warnings just makes it quicker to figure out if the test fails for the right reason.

Note that code links printed to the console are clickable in any decent IDE (e.g. Eclipse).

So far I identified 2 cases when warnings are printed:

  • unsued stub
  • stubbed method but called with different arguments

  • Do you think it is useful or not? Drop us an email at [email protected]


    Constructor Summary
    ConsoleSpammingMockitoJUnitRunner(java.lang.Class<?> klass)
               
     
    Method Summary
     void filter(org.junit.runner.manipulation.Filter filter)
               
     org.junit.runner.Description getDescription()
               
     void run(org.junit.runner.notification.RunNotifier notifier)
               
     
    Methods inherited from class org.junit.runner.Runner
    testCount
     
    Methods inherited from class java.lang.Object
    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
     

    Constructor Detail

    ConsoleSpammingMockitoJUnitRunner

    public ConsoleSpammingMockitoJUnitRunner(java.lang.Class<?> klass)
                                      throws java.lang.reflect.InvocationTargetException
    Throws:
    java.lang.reflect.InvocationTargetException
    Method Detail

    run

    public void run(org.junit.runner.notification.RunNotifier notifier)
    Specified by:
    run in class org.junit.runner.Runner

    getDescription

    public org.junit.runner.Description getDescription()
    Specified by:
    getDescription in interface org.junit.runner.Describable
    Specified by:
    getDescription in class org.junit.runner.Runner

    filter

    public void filter(org.junit.runner.manipulation.Filter filter)
                throws org.junit.runner.manipulation.NoTestsRemainException
    Specified by:
    filter in interface org.junit.runner.manipulation.Filterable
    Throws:
    org.junit.runner.manipulation.NoTestsRemainException