Repository: mockito/mockito
Issue: Refactor instance based utility classes to static utility classes

The internal implementation of Mockito contains numerous helper classed that serve as a container for useful methods. By its nature these classes don't have a state. Currently some them are instance based in other word you need to create the utility class to call a helper method. This not only pollutes the heap but also the code cause instance methods can't be imported statically. 

Here is an example:

```java
Helper helper = new Helper();
if (helper.isInputValid(input)){
  [...] 
}
```

vs. static import of Helper.isInputValid

```java
if (isInputValid(input)){
  [...] 
}
```

The aim of this ticket is to identify canidates that can be refactored to static utility classes. If you like to refactoring and mockito feel free to send a PR and reference this issue.

Refactoring canidates:
- [ ] `AccessibilityChanger`
- [ ] `BeanPropertySetter`
- [ ] `ConditionalStackTraceFilter`
- [ ] `FieldCopier`
- [ ] `FieldReader`
- [ ] `GenericMaster` should be integrate into `GenericTypeResolver`
- [ ] `JUnitFailureHacker` can be removed when the deprecated `VerboseMockitoJUnitRunner` is removed
- [ ] `LenientCopyTool`
- [ ] `MatcherBinder`
- [ ] `MockitoCore` should better be a singleton
- [x] `MockCreationValidator`
- [ ] `RemoveFirstLine`
- [x] #591 `ArgumentMatchingTool`
- [x] #515 `AllInvocationsFinder`
- [x] #502 `ArgumentsComparator`
- [x] #540 `ArrayUtils`
- [x] #490 `AtLeastXNumberOfInvocationsChecker`
- [x] #490 `AtLeastXNumberOfInvocationsInOrderChecker`
- [ ] #912 `Constructors`
- [x] #427 `FieldSetter`
- [x] #908 `FriendlyExceptionMaker`
- [x] #431 `HandyReturnValues` 
- [x] #432 `InvocationMarker`
- [x] #462 `InvocationsFinder`
- [x] #908 `JUnitDetecter`
- [x] #490 `MissingInvocationChecker`
- [x] #490 `MissingInvocationInOrderChecker`
- [x] #514 `MockUtil`
- [x] #503 `NonGreedyNumberOfInvocationsInOrderChecker`
- [x] #907 `NumberOfInvocationsInOrderChecker`
- [x] #907 `NumberOfInvocationsChecker`
- [x] #547 `ObjectMethodsGuru`
- [x] #427 `Reporter`
- [x] #535 `SuperTypesLastSorter`
- [x] #501 `TestMethodFinder`
- [x] #515 `VerifiableInvocationsFinder`


Issue comments:
@raphw thanks for merging the PR that fast!  Would you mind reopening this ticket? There are more classes that can be refactored that way, I would like to extend the list.

Big :+1: for me btw, but please keep the pull requests managable and as small as possible. Preferably refactoring 1 method at a time. That way it is a lot easier to review.

I agree, there is nothing wrong with multiple PRs, the quick merge is a reaction to an easy overview (and being stuck at an Ukrainian airport without access to the Eurocup).

There are still two unit tests failing, could you have a look @ChristianSchwarz - I just had a quick look and there are two unit tests failing which seems related to the way you refactored the previous stubbing of the `Reporter`.

I should have checked more thoroughly before merging, hopefully you can fix the problem soon. Alternatively, I will just rollback the one commit (the first one is good) and we can reapply the patch once you fixed the two unit tests. Thank you, really, this was great clean-up.

I fixed the one test error. I push it tonight.

PS: I also fixed a bug in the stack trace cleaner. Not a biggy but please do not `@Ignore` tests. Especially in big commits, it is easy to miss that single annotation.

@raphw Which test(s) is/are failing? I will fix it asap! Too bad that some test fail on a regulare base, is it possible to ignore them in the ide only?

You can see the build output here: https://travis-ci.org/mockito/mockito#L254-L269

I advise you to run the tests with `./gradlew build`. This should work.

@TimvdLippe know what you mean! The next PR's include only one refactored class at a time.

I have it all fixed on local but I did not have access to wifi without 22 blocked. Will commit soon.

@raphw can you please reopen this issue 

Sorry, GitHub automatically closes issues that reference a PR.

@ChristianSchwarz If a commit contains a comment like "Fixes #426" the mentioned issue is automatically closed by github.

@PascalSchumacher Good to know! I will leave it out for the upcoming PR's. Thanks!

Now that we are pulling in static methods, I would like to propose a new (linter) rule. To make it easier to read a file, I would like that all methods invoked in the current class are referenced with `this.` (and `super.` for that matter). Therefore if we see `this.verify`, we know it is in the current class and the same object, whereas `verify` references a static method in this class, or an imported static method. Do you agree @mockito/developers ?

> I would like that all methods invoked in the current class are referenced with this. (and super. for that matter).

To me it feels like unnecessary/duplicate code cause `this` is implicit. Adding `this.` before every instance call would create a lot more text and would IMHO reduce readability. E.g.:

`this.doSometing(this.withPrivateMethod())` vs. `doSomething(withPrivateMethod())`

> Therefore if we see this.verify, we know it is in the current class and the same object, whereas verify references a static method in this class, or an imported static method.

An other option avoid ambiguity is to qualify static methods via its class name.  This way you can also distinguish which verify(..) is called ( `MockitoCore.verify(..)` / `Mocktio.verify(..)`) , which is not an easy task when a static import is used.

I'm not coding too much in Mockito ATM (hopefully now after SpringOne conference I'll have more time) but I fully agree with @ChristianSchwarz . IMO the best solution is to: 
- omit `this` before method calls. 
- if necessary provide the class for static method call

Respectful -1

I like when the class formally declares collaborators instead of calling out to static methods. This makes it easy to reason about the code. I don't need to read every line of code in the class to find out external couplings realized via static methods. I can see the couplings via fields, I can easily query how the field variable is used, etc. Another use case is when we discover missing/incorrect unit test coverage (or we do some larger refactorings) and we cannot easily write tests because code is too procedural.

The benefits for converting to static utilities have minimal significance to me. Yet, there is a downside I care about (e.g. maintainability of procedural code, static methods that consume static methods, that consume static methods...).

Hence, I down vote this sort of changes. Going down this path, all stateless classes in Mockito would become static utilities :)

You can get +1's from other maintainers and have your changes merged - I'm not here to block your changes but to give honest feedback. I see merit in arguments for static utilities. They do not outweigh the cost in my opinion.

I'm mitigated about this as well. I understand well that mockito creates garbage, but they are short lived and **most probably** won't go in the old generation especially in the test phase. Yet the faster the tests are the more developers will run them, it **may** have impacts on big projects. Also design wise I don't like much static methods too.

However I don't totally agree with the above points : 

> I don't need to read every line of code in the class to find out external couplings realized via static methods. I can see the couplings via fields, I can easily query how the field variable is used, etc.

Coupling appears also in the import section ; static methods are visible there. And modern IDE usually highlight this. IntelliJ even have a warning if import section is too big, just as there's warning if there's too many fields. This point should not be the reason to avoid static methods.

> maintainability of procedural code, static methods that consume static methods, that consume static methods...

Having instance methods does not protect again procedural code.

---

I believe there's middle ground there : 
- Mockito project contains a lot of small utility stateless objects that are supporting mockito features, these are usually collections tools, reflection tools, those could are good candidate for static methods. Objects like `FieldSetter`, `FieldCopier`, `LenientCopyTool` could be nice candidate for static methods
- Mockito features could be backed by object instances. Objects like `MockitoCore`, `MockCreationValidator`, `ArgumentMatchingTool` are candidate to stay objects.

Exactly the middle ground described by Brice is my motivation for merging most of the PRs. This is also the reason I have not yet merged the MockitoCore PR for this exact reason.

If an object is not a attribute or parameter, but an internal creation and immediately dismissed, I value a pure function more.

Thought: when we switch to Java 8, we can use interfaces with default
methods. The switch from static utility to interface is very easy now (just
a couple of text replaces, no method reference modifications).

On Fri, 12 Aug 2016, 17:23 Brice Dutheil, notifications@github.com wrote:

> I'm mitigated about this as well. I understand well that mockito creates
> garbage, but they are short lived and _most probably_ won't go in the old
> generation especially in the test phase. Yet the faster the tests are the
> more developers will run them, it _may_ have impacts on big projects.
> Also design wise I don't like much static methods too.
> 
> However I don't totally agree with the above points :
> 
> I don't need to read every line of code in the class to find out external
> couplings realized via static methods. I can see the couplings via fields,
> I can easily query how the field variable is used, etc.
> 
> Coupling appears also in the import section ; static methods are visible
> there. And modern IDE usually highlight this. IntelliJ even have a warning
> if import section is too big, just as there's warning if there's too many
> fields. This point should not be the reason to avoid static methods.
> 
> maintainability of procedural code, static methods that consume static
> methods, that consume static methods...
> 
> ## Having instance methods does not protect again procedural code.
> 
> I believe there's middle ground there :
> 
>    -
> 
>    Mockito project contains a lot of small utility stateless objects that
>    are supporting mockito features, these are usually collections tools,
>    reflection tools, those could are good candidate for static methods.
>    Objects like FieldSetter, FieldCopier, LenientCopyTool could be nice
>    candidate for static methods
>    -
> 
>    Mockito features could be backed by object instances. Objects like
>    MockitoCore, MockCreationValidator, ArgumentMatchingTool are candidate
>    to stay objects.
> 
> —
> You are receiving this because you modified the open/close state.
> Reply to this email directly, view it on GitHub
> https://github.com/mockito/mockito/issues/426#issuecomment-239476519,
> or mute the thread
> https://github.com/notifications/unsubscribe-auth/AFrDb6QVlVesWgPAhurimgSUPQTRcTZSks5qfJALgaJpZM4IzjKm
> .

This feels like a misuse of the default methods.

I think you mean static-methods in interfaces here? Default-methods require an instance to be called on.
Anyway I don't think that it is a good idea.  It would a result in an interface that is not intended to be implemented or extended and only serves as container for utility methods. IMHO a class with private constructor is the best construct to do this.

> > Thought: when we switch to Java 8, we can use interfaces with default
> > methods.
> 
> Default-methods require an instance to be called on.

I was thinking exactly that, default methods in the interface plus instance (either as a separate file or as a singleton declared within the interface).

@ChristianSchwarz What do you think to continue the work here with the middle ground described [here](https://github.com/mockito/mockito/issues/426#issuecomment-239476519) ?

I am attempting to refactor the MatcherBinder class to a static utility class and am having trouble refactoring the following from MockHandlerImplTest.java: `
handler.matchersBinder = new MatchersBinder() {
            public InvocationMatcher bindMatchers(ArgumentMatcherStorage argumentMatcherStorage, Invocation invocation) {
                throw new InvalidUseOfMatchersException();
            }
}; `
How can I maintain the abstract class definition when I am not able to create an object of MatcherBinder?

Any help is appreciated! 
Let's close this ticket. Refactorings can be done as needed as we work with the code.

Pull request review comments:

Patch that resolved the issue:
diff --git a/src/main/java/org/mockito/internal/verification/Calls.java b/src/main/java/org/mockito/internal/verification/Calls.java
index e7e7eeef0d..3d9bc84fa7 100644
--- a/src/main/java/org/mockito/internal/verification/Calls.java
+++ b/src/main/java/org/mockito/internal/verification/Calls.java
@@ -5,20 +5,18 @@
 
 package org.mockito.internal.verification;
 
+import static org.mockito.internal.verification.checkers.MissingInvocationChecker.checkMissingInvocation;
+import static org.mockito.internal.verification.checkers.NumberOfInvocationsChecker.checkNumberOfInvocationsNonGreedy;
+
+import java.util.List;
 import org.mockito.exceptions.base.MockitoException;
-import org.mockito.internal.invocation.InvocationMatcher;
-import org.mockito.invocation.MatchableInvocation;
 import org.mockito.internal.verification.api.VerificationData;
 import org.mockito.internal.verification.api.VerificationDataInOrder;
 import org.mockito.internal.verification.api.VerificationInOrderMode;
 import org.mockito.invocation.Invocation;
+import org.mockito.invocation.MatchableInvocation;
 import org.mockito.verification.VerificationMode;
 
-import static org.mockito.internal.verification.checkers.NonGreedyNumberOfInvocationsInOrderChecker.check;
-import static org.mockito.internal.verification.checkers.MissingInvocationChecker.checkMissingInvocation;
-
-import java.util.List;
-
 public class Calls implements VerificationMode, VerificationInOrderMode {
 
     final int wantedCount;
@@ -30,16 +28,18 @@ public Calls(int wantedNumberOfInvocations) {
         this.wantedCount = wantedNumberOfInvocations;
     }
 
+    @Override
     public void verify(VerificationData data) {
         throw new MockitoException( "calls is only intended to work with InOrder" );
     }
 
+    @Override
     public void verifyInOrder(VerificationDataInOrder data) {
         List<Invocation> allInvocations = data.getAllInvocations();
         MatchableInvocation wanted = data.getWanted();
 
         checkMissingInvocation(allInvocations, wanted,  data.getOrderingContext());
-        check( allInvocations, wanted, wantedCount, data.getOrderingContext());
+        checkNumberOfInvocationsNonGreedy(allInvocations, wanted, wantedCount, data.getOrderingContext());
     }    
     
     @Override
diff --git a/src/main/java/org/mockito/internal/verification/Times.java b/src/main/java/org/mockito/internal/verification/Times.java
index 5dbf0f444c..d2895c5446 100644
--- a/src/main/java/org/mockito/internal/verification/Times.java
+++ b/src/main/java/org/mockito/internal/verification/Times.java
@@ -6,16 +6,14 @@
 package org.mockito.internal.verification;
 
 import static org.mockito.internal.verification.checkers.MissingInvocationChecker.checkMissingInvocation;
+import static org.mockito.internal.verification.checkers.NumberOfInvocationsChecker.checkNumberOfInvocations;
 
 import java.util.List;
 import org.mockito.exceptions.base.MockitoException;
-import org.mockito.internal.invocation.InvocationMatcher;
 import org.mockito.invocation.MatchableInvocation;
 import org.mockito.internal.verification.api.VerificationData;
 import org.mockito.internal.verification.api.VerificationDataInOrder;
 import org.mockito.internal.verification.api.VerificationInOrderMode;
-import org.mockito.internal.verification.checkers.NumberOfInvocationsChecker;
-import org.mockito.internal.verification.checkers.NumberOfInvocationsInOrderChecker;
 import org.mockito.invocation.Invocation;
 import org.mockito.verification.VerificationMode;
 
@@ -30,6 +28,7 @@ public Times(int wantedNumberOfInvocations) {
         this.wantedCount = wantedNumberOfInvocations;
     }
     
+    @Override
     public void verify(VerificationData data) {
         List<Invocation> invocations = data.getAllInvocations();
         MatchableInvocation wanted = data.getTarget();
@@ -37,10 +36,10 @@ public void verify(VerificationData data) {
         if (wantedCount > 0) {
              checkMissingInvocation(data.getAllInvocations(), data.getTarget());
         }
-        NumberOfInvocationsChecker numberOfInvocations = new NumberOfInvocationsChecker();
-        numberOfInvocations.check(invocations, wanted, wantedCount);
+        checkNumberOfInvocations(invocations, wanted, wantedCount);
     }
     
+    @Override
     public void verifyInOrder(VerificationDataInOrder data) {
         List<Invocation> allInvocations = data.getAllInvocations();
         MatchableInvocation wanted = data.getWanted();
@@ -48,8 +47,7 @@ public void verifyInOrder(VerificationDataInOrder data) {
         if (wantedCount > 0) {
             checkMissingInvocation(allInvocations, wanted, data.getOrderingContext());
         }
-        NumberOfInvocationsInOrderChecker numberOfCalls = new NumberOfInvocationsInOrderChecker();
-        numberOfCalls.check(allInvocations, wanted, wantedCount, data.getOrderingContext());
+        checkNumberOfInvocations(allInvocations, wanted, wantedCount, data.getOrderingContext());
     }    
     
     @Override
diff --git a/src/main/java/org/mockito/internal/verification/checkers/NonGreedyNumberOfInvocationsInOrderChecker.java b/src/main/java/org/mockito/internal/verification/checkers/NonGreedyNumberOfInvocationsInOrderChecker.java
deleted file mode 100644
index 3bccd0a396..0000000000
--- a/src/main/java/org/mockito/internal/verification/checkers/NonGreedyNumberOfInvocationsInOrderChecker.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-
-package org.mockito.internal.verification.checkers;
-
-import static org.mockito.internal.exceptions.Reporter.tooLittleActualInvocationsInOrder;
-import static org.mockito.internal.invocation.InvocationMarker.markVerified;
-import static org.mockito.internal.invocation.InvocationsFinder.findFirstMatchingUnverifiedInvocation;
-
-import java.util.List;
-
-import org.mockito.internal.invocation.InvocationMatcher;
-import org.mockito.internal.reporting.Discrepancy;
-import org.mockito.internal.verification.api.InOrderContext;
-import org.mockito.invocation.Invocation;
-import org.mockito.invocation.Location;
-import org.mockito.invocation.MatchableInvocation;
-
-public class NonGreedyNumberOfInvocationsInOrderChecker {
-
-    private NonGreedyNumberOfInvocationsInOrderChecker() {}
-
-    public static void check(List<Invocation> invocations, MatchableInvocation wanted, int wantedCount, InOrderContext context) {
-        int actualCount = 0;
-        Location lastLocation = null;
-        while( actualCount < wantedCount ){
-            Invocation next = findFirstMatchingUnverifiedInvocation(invocations, wanted, context );
-            if( next == null ){
-                throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, lastLocation );
-            }
-            markVerified( next, wanted );
-            context.markVerified( next );
-            lastLocation = next.getLocation();
-            actualCount++;
-        }
-    }
-}
diff --git a/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java b/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java
index 938f8ffd32..531f4779c4 100644
--- a/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java
+++ b/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java
@@ -7,20 +7,29 @@
 
 import java.util.List;
 import org.mockito.internal.reporting.Discrepancy;
+import org.mockito.internal.verification.api.InOrderContext;
 import org.mockito.invocation.Invocation;
 import org.mockito.invocation.Location;
 import org.mockito.invocation.MatchableInvocation;
 
 import static org.mockito.internal.exceptions.Reporter.neverWantedButInvoked;
 import static org.mockito.internal.exceptions.Reporter.tooLittleActualInvocations;
+import static org.mockito.internal.exceptions.Reporter.tooLittleActualInvocationsInOrder;
 import static org.mockito.internal.exceptions.Reporter.tooManyActualInvocations;
+import static org.mockito.internal.exceptions.Reporter.tooManyActualInvocationsInOrder;
 import static org.mockito.internal.invocation.InvocationMarker.markVerified;
+import static org.mockito.internal.invocation.InvocationMarker.markVerifiedInOrder;
+import static org.mockito.internal.invocation.InvocationsFinder.findFirstMatchingUnverifiedInvocation;
 import static org.mockito.internal.invocation.InvocationsFinder.findInvocations;
+import static org.mockito.internal.invocation.InvocationsFinder.findMatchingChunk;
 import static org.mockito.internal.invocation.InvocationsFinder.getLastLocation;
 
 public class NumberOfInvocationsChecker {
+    
+    private NumberOfInvocationsChecker() {
+    }
 
-    public void check(List<Invocation> invocations, MatchableInvocation wanted, int wantedCount) {
+    public static void checkNumberOfInvocations(List<Invocation> invocations, MatchableInvocation wanted, int wantedCount) {
         List<Invocation> actualInvocations = findInvocations(invocations, wanted);
         
         int actualCount = actualInvocations.size();
@@ -39,4 +48,36 @@ public void check(List<Invocation> invocations, MatchableInvocation wanted, int
 
         markVerified(actualInvocations, wanted);
     }
+    
+    public static void checkNumberOfInvocations(List<Invocation> invocations, MatchableInvocation wanted, int wantedCount, InOrderContext context) {
+        List<Invocation> chunk = findMatchingChunk(invocations, wanted, wantedCount, context);
+        
+        int actualCount = chunk.size();
+        
+        if (wantedCount > actualCount) {
+            Location lastInvocation = getLastLocation(chunk);
+            throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, lastInvocation);
+        } 
+        if (wantedCount < actualCount) {
+            Location firstUndesired = chunk.get(wantedCount).getLocation();
+            throw tooManyActualInvocationsInOrder(wantedCount, actualCount, wanted, firstUndesired);
+        }
+        
+        markVerifiedInOrder(chunk, wanted, context);
+    }
+    
+    public static void checkNumberOfInvocationsNonGreedy(List<Invocation> invocations, MatchableInvocation wanted, int wantedCount, InOrderContext context) {
+        int actualCount = 0;
+        Location lastLocation = null;
+        while( actualCount < wantedCount ){
+            Invocation next = findFirstMatchingUnverifiedInvocation(invocations, wanted, context );
+            if( next == null ){
+                throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, lastLocation );
+            }
+            markVerified( next, wanted );
+            context.markVerified( next );
+            lastLocation = next.getLocation();
+            actualCount++;
+        }
+    }
 }
diff --git a/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderChecker.java b/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderChecker.java
deleted file mode 100644
index 0445b383ee..0000000000
--- a/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderChecker.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-
-package org.mockito.internal.verification.checkers;
-
-import static org.mockito.internal.exceptions.Reporter.tooLittleActualInvocationsInOrder;
-import static org.mockito.internal.exceptions.Reporter.tooManyActualInvocationsInOrder;
-import static org.mockito.internal.invocation.InvocationMarker.markVerifiedInOrder;
-import static org.mockito.internal.invocation.InvocationsFinder.findMatchingChunk;
-import static org.mockito.internal.invocation.InvocationsFinder.getLastLocation;
-
-import java.util.List;
-
-import org.mockito.internal.invocation.InvocationMatcher;
-import org.mockito.internal.reporting.Discrepancy;
-import org.mockito.internal.verification.api.InOrderContext;
-import org.mockito.invocation.Invocation;
-import org.mockito.invocation.Location;
-import org.mockito.invocation.MatchableInvocation;
-
-public class NumberOfInvocationsInOrderChecker {
-  
-    public void check(List<Invocation> invocations, MatchableInvocation wanted, int wantedCount, InOrderContext context) {
-        List<Invocation> chunk = findMatchingChunk(invocations, wanted, wantedCount, context);
-        
-        int actualCount = chunk.size();
-        
-        if (wantedCount > actualCount) {
-            Location lastInvocation = getLastLocation(chunk);
-            throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, lastInvocation);
-        } 
-        if (wantedCount < actualCount) {
-            Location firstUndesired = chunk.get(wantedCount).getLocation();
-            throw tooManyActualInvocationsInOrder(wantedCount, actualCount, wanted, firstUndesired);
-        }
-        
-        markVerifiedInOrder(chunk, wanted, context);
-    }
-}


Test patch:
diff --git a/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsCheckerTest.java b/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsCheckerTest.java
index d692fac57d..af9d3cb801 100644
--- a/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsCheckerTest.java
+++ b/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsCheckerTest.java
@@ -5,10 +5,14 @@
 
 package org.mockito.internal.verification.checkers;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -24,17 +28,9 @@
 import org.mockito.junit.MockitoJUnitRunner;
 import org.mockitousage.IMethods;
 
-import java.util.List;
-
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static org.assertj.core.api.Assertions.assertThat;
-
 @RunWith(MockitoJUnitRunner.class)
 public class NumberOfInvocationsCheckerTest {
 
-    private NumberOfInvocationsChecker checker;
-
     private InvocationMatcher wanted;
 
     private List<Invocation> invocations;
@@ -48,12 +44,6 @@ public class NumberOfInvocationsCheckerTest {
     @Rule
     public TestName testName = new TestName();
 
-    @Before
-    public void setup() {
-        checker = new NumberOfInvocationsChecker();
-
-    }
-
     @Test
     public void shouldReportTooLittleActual() throws Exception {
         wanted = buildSimpleMethod().toInvocationMatcher();
@@ -64,7 +54,7 @@ public void shouldReportTooLittleActual() throws Exception {
         exception.expectMessage("Wanted 100 times");
         exception.expectMessage("But was 2 times");
 
-        checker.check(invocations, wanted, 100);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100);
     }
 
     @Test
@@ -78,7 +68,7 @@ public void shouldReportWithLastInvocationStackTrace() throws Exception {
         exception.expectMessage("But was 2 times");
         exception.expectMessage(containsTimes("-> at", 2));
 
-        checker.check(invocations, wanted, 100);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100);
     }
 
     @Test
@@ -92,7 +82,7 @@ public void shouldNotReportWithLastInvocationStackTraceIfNoInvocationsFound() th
         exception.expectMessage("But was 0 times");
         exception.expectMessage(containsTimes("-> at", 1));
 
-        checker.check(invocations, wanted, 100);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100);
     }
 
     @Test
@@ -106,7 +96,7 @@ public void shouldReportWithFirstUndesiredInvocationStackTrace() throws Exceptio
 
         exception.expect(TooManyActualInvocations.class);
         exception.expectMessage("" + third.getLocation());
-        checker.check(invocations, wanted, 2);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 2);
     }
 
     @Test
@@ -120,7 +110,7 @@ public void shouldReportTooManyActual() throws Exception {
         exception.expectMessage("Wanted 1 time");
         exception.expectMessage("But was 2 times");
 
-        checker.check(invocations, wanted, 1);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1);
     }
 
     @Test
@@ -135,7 +125,7 @@ public void shouldReportNeverWantedButInvoked() throws Exception {
         exception.expectMessage("But invoked here");
         exception.expectMessage("" + first.getLocation());
 
-        checker.check(invocations, wanted, 0);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 0);
     }
 
 	@Test
@@ -145,7 +135,7 @@ public void shouldMarkInvocationsAsVerified() throws Exception {
 
 		invocations = asList(invocation);
 		wanted = buildSimpleMethod().toInvocationMatcher();
-		checker.check(invocations, wanted, 1);
+		NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1);
 		assertThat(invocation.isVerified()).isTrue();
 	}
 
diff --git a/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderCheckerTest.java b/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderCheckerTest.java
index 4b1784125d..2e72033238 100644
--- a/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderCheckerTest.java
+++ b/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderCheckerTest.java
@@ -12,7 +12,6 @@
 
 import java.util.List;
 
-import org.assertj.core.api.Assertions;
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
@@ -30,7 +29,6 @@
 
 public class NumberOfInvocationsInOrderCheckerTest {
 
-    private NumberOfInvocationsInOrderChecker checker;
     private InvocationMatcher wanted;
     private List<Invocation> invocations;
     private InOrderContext context;
@@ -42,7 +40,6 @@ public class NumberOfInvocationsInOrderCheckerTest {
 
     @Before
     public void setup() {
-        checker = new NumberOfInvocationsInOrderChecker();
         context = new InOrderContextImpl();
         mock = mock(IMethods.class, "mock");
 
@@ -53,14 +50,14 @@ public void shouldPassIfWantedIsZeroAndMatchingChunkIsEmpty() {
         wanted = buildSimpleMethod().toInvocationMatcher();
         invocations = emptyList();
 
-        checker.check(invocations, wanted, 0, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 0, context);
     }
 
     @Test
     public void shouldPassIfChunkMatches() throws Exception {
         wanted = buildSimpleMethod().toInvocationMatcher();
         invocations = asList(buildSimpleMethod().toInvocation());
-        checker.check(invocations, wanted, 1, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1, context);
     }
 
     @Test
@@ -76,7 +73,7 @@ public void shouldReportTooLittleInvocations() throws Exception {
         exception.expectMessage("Wanted 4 times");
         exception.expectMessage("But was 2 times");
 
-        checker.check(invocations, wanted, 4, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 4, context);
     }
 
     @Test
@@ -87,7 +84,7 @@ public void shouldMarkAsVerifiedInOrder() throws Exception {
         wanted = buildSimpleMethod().toInvocationMatcher();
 
         assertThat(context.isVerified(invocation)).isFalse();
-        checker.check(invocations, wanted, 1, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1, context);
         assertThat(context.isVerified(invocation)).isTrue();
     }
 
@@ -101,7 +98,7 @@ public void shouldReportTooLittleActual() throws Exception {
         exception.expectMessage("Wanted 100 times");
         exception.expectMessage("But was 2 times");
 
-        checker.check(invocations, wanted, 100, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100, context);
     }
 
     @Test
@@ -115,7 +112,7 @@ public void shouldReportWithLastInvocationStackTrace() throws Exception {
         exception.expectMessage("But was 2 times");
         exception.expectMessage(containsTimes("-> at", 2));
 
-        checker.check(invocations, wanted, 100, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100, context);
 
     }
 
@@ -130,7 +127,7 @@ public void shouldNotReportWithLastInvocationStackTraceIfNoInvocationsFound() th
         exception.expectMessage("But was 0 times");
         exception.expectMessage(containsTimes("-> at", 1));
 
-        checker.check(invocations, wanted, 100, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100, context);
     }
 
     @Test
@@ -144,7 +141,7 @@ public void shouldReportWithFirstUndesiredInvocationStackTrace() throws Exceptio
 
         exception.expect(VerificationInOrderFailure.class);
         exception.expectMessage("" + third.getLocation());
-        checker.check(invocations, wanted, 2, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 2, context);
     }
 
     @Test
@@ -158,7 +155,7 @@ public void shouldReportTooManyActual() throws Exception {
         exception.expectMessage("Wanted 1 time");
         exception.expectMessage("But was 2 times");
 
-        checker.check(invocations, wanted, 1, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1, context);
     }
 
     @Test
@@ -174,17 +171,17 @@ public void shouldReportNeverWantedButInvoked() throws Exception {
         exception.expectMessage("But was 1 time. Undesired invocation");
         exception.expectMessage("" + first.getLocation());
 
-        checker.check(invocations, wanted, 0, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 0, context);
     }
 
     @Test
     public void shouldMarkInvocationsAsVerified() throws Exception {
         Invocation invocation = buildSimpleMethod().toInvocation();
-        Assertions.assertThat(invocation.isVerified()).isFalse();
+        assertThat(invocation.isVerified()).isFalse();
 
         invocations = asList(invocation);
         wanted = buildSimpleMethod().toInvocationMatcher();
-        checker.check(invocations, wanted, 1, context);
+        NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1, context);
         assertThat(invocation.isVerified()).isTrue();
     }
 
@@ -203,6 +200,7 @@ private static class StringContainsNumberMatcher extends TypeSafeMatcher<String>
             this.amount = amount;
         }
 
+        @Override
         public boolean matchesSafely(String text) {
             int lastIndex = 0;
             int count = 0;
@@ -216,6 +214,7 @@ public boolean matchesSafely(String text) {
             return count == amount;
         }
 
+        @Override
         public void describeTo(Description description) {
             description.appendText("containing '" + expected + "' exactly " + amount + " times");
         }