Mockito methods are not accessible - mockito

I have mockito setup on my project with this maven lines:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>
I have no problems to use the #Mock annotation but I can't access and use mockito methods like:
when(someMock.someMethod()).thenReturn();
Eclipse just does not recognize them.
Please help.

Try calling Mockito.when(foo.getBar()).thenReturn(baz) and Mockito.verify(foo).getBar(), which won't rely on static imports. Unlike the #Mock annotation, which is technically a class, when and verify are static methods on the Mockito class.
Once you have that working, then try the static imports to which David alluded:
import static org.mockito.Mockito.when; // ...or...
import static org.mockito.Mockito.*; // ...with the caveat noted below.
This will then allow you to use Mockito.when without specifying the Mockito class. You can also use a wildcard, as so, but per this SO answer the Java docs recommend using wildcards sparingly--especially since it can break if a similarly-named static method is ever added to Mockito later.
Adding import org.mockito.*; is insufficient because that adds all classes in the org.mockito package, but not the methods on org.mockito.Mockito.
For Eclipse in particular, you can add a static import by putting the cursor on the when part of Mockito.when and pressing Control-Shift-M ("Add import"). You can also add org.mockito.Mockito to your Favorites (Window > Preferences > Java > Editor > Content Assist > Favorites > New Type) so that all Mockito static methods show up in your Ctrl-Space content assist prompt even if you haven't imported them specifically. (You may also want to do this for org.mockito.Matchers, which are technically available on org.mockito.Mockito via inheritance, but may not show up in Eclipse for that reason.)

Kotlin syntax - dont forget the ` ` backticks:
import org.mockito.Mockito.`when`
`when`(someMock.someMethod()).thenReturn();

Related

Using mockito any() throws java.lang.IllegalAccessError: class org.mockito.Matchers tried to access private method

I'm facing the exception
java.lang.IllegalAccessError: class org.mockito.Matchers tried to access private method 'void org.mockito.internal.progress.ThreadSafeMockingProgress.()' (org.mockito.Matchers and org.mockito.internal.progress.ThreadSafeMockingProgress are in unnamed module of loader 'app')
at org.mockito.Matchers.(Matchers.java:107)
when I try to use the matcher any() in mockito when() stub call. The class argument type is for "NewOrder" from the binance spot java library here
I'm trying to do
when(mockBinanceApiRestClient.newOrder(any(NewOrder.class))).thenReturn(buyOrderResp);
mocking the BinanceApiRestClient.
The any() and when() are static imports from org.mockito.Mockito.
This is such a nightmare why it wouldn't work. Any help is much appreciated.
Looks like you have two conflicting versions of Mockito on your classpath.
ThreadSafeMockingProgress was converted to a singleton back in 2016, and its constructor was changed to private.
On the other hand, you seem to be using org.mockito.Matchers,
which was deprecated for a long while and finally removed in Mockito 4.x
I also faced similar issue when we used below dependency -
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
<scope>test</scope>
</dependency>
we had below import statements which were causing IllegalAccess exception
import static org.mockito.Matchers.any;
I replaced Matchers with ArgumentMatchers as below -
import static org.mockito.ArgumentMatchers.any;
This resolved the issue.

Mocking System class method using testng, mockito and powermock

I am currently writing tests to a legacy code which uses a function System.getenv("some_environment_variable")
I get a problem when I try to mock these variables by using mockito and powermock (used under testng framework)
What I did so far was
#BeforeClass
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getenv("hello")).thenReturn("world");
}
#Test
public void test() {
assertEquals(System.getenv("hello"), "world");
}
But when I tried to run the code above i get the following error:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
you stub either of: final/private/equals()/hashCode() methods.
Those methods cannot be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
inside when() you don't call method on mock but on some other object.
So Iv'e read and saw that this error raised when trying to mock a method with mocking the class itself, but this is not the case here.
After toying around with this for quite sometime, here's how I managed to do it.
In a nutshell, in order to get powermockito and TestNG to work with each other you have to do the following (quoting from the blog post whose link is shared below so that the answer is complete and will be useful even if the blog is not available at a later point in time)
Configure TestNG to use the PowerMock object factory : You can do this either via the attribute object-factory in your <suite> tag of your suite xml or via an #org.testng.annotations.ObjectFactory annotated method which returns the powermock's implementation of TestNG interface org.testng.IObjectFactory viz., org.powermock.modules.testng.PowerMockObjectFactory (or) by extending org.powermock.modules.testng.PowerMockTestCase
Use #PrepareForTest to prepare your static class for being mocked by PowerMockito
Please refer to this blog for more details.
Here's a working sample:
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.testng.IObjectFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
#PrepareForTest(System.class)
public class SampleTestClass {
#BeforeClass
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getenv("hello")).thenReturn("world");
}
#Test
public void test() {
assertEquals(System.getenv("hello"), "world");
}
#ObjectFactory
public IObjectFactory getObjectFactory() {
return new org.powermock.modules.testng.PowerMockObjectFactory();
}
}
I used the below dependencies for creating this sample
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-testng</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
There is another JUnit library which may help you: system-rules, which will allow you to -- among other things -- set and restore environment variables. It is used in conjunction with JUnit #Rules

Cucumber-serenity not inject Steps

I´m using cucumber-selenium to run some integration tests. I manage to create the feature file and the Test class. But once that I´m in my Give method I see that the ScenarioSteps(ProjectMemberSteps) class that I define to talk with the object page is null.
I was expecting to be injected like JBehave does.
public class OrderTest extends StepsLibrary {
#Steps ProjectMemberSteps projectManager;//This one is null
#Before
public void beforeScenarios() throws Exception {
initializeDemoUIServer();
}
#Given("I open the login page")
public void openLoginPage(){
projectManager.openLoginPage();
}
}
This is the Scenario runner class for the test
/**
* Serenity story for login.
*/
#RunWith(CucumberWithSerenity.class)
#CucumberOptions(features="src/test/resources/features/order/order.feature",
glue = Order.BEHAVIOUR_PACKAGE)
public class Order {
public static final String BEHAVIOUR_PACKAGE = "com.behaviour.steps.serenity";
}
This is class ProjectMemberSteps is under steps/serenity/ as the documentation suggest.
I´m using Maven, and the libraries that I´m using are
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-cucumber</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-junit</artifactId>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>core</artifactId>
<version>1.0.47</version>
</dependency>
Anyway this particular test I´m running with the IDE and not through Maven, but I was expecting that "ProjectMemberSteps" would be inject as JBehave use to do.
Any idea what´s wrong?
Regards.
I am also a newbie. I don't see any problem with your OrderTest.java class except it is unnecessarily extending a class called StepsLibrary. In Java-Cucumber, I don't extend any other class. Only exception is When
StepDefinition file(your OrderTest.java) delegates method calls to xxxxSteps.java class and which in turn delegates to xxxPageObject.java (which MUST extend PageObject class from Serenity import net.serenitybdd.core.pages.PageObject;)
I assume Before annotation is to repeat a scenario. Instead another alternative is Background keyword to be used in the feature file itself. I don't claim any advantage with this though.
Per me, Your Test Runner class should only give the package in which xxxxStepDefinitions.java resides, simply like glue = {"stepdefinitions"}, curly braces are optional I believe.
The rest looks perfectly OK to me. Including defining
#Steps ProjectMemberSteps projectManager;
Try one more time.

Add constraints to properties of Groovy class (not Grails domain class!)

How can we add some common constraints (i.e. maxLength, nullable) to a property of a Groovy class? I know we can do it at Grails domain class, but is it possible if that is a Groovy class (I use it as a DTO class for my Grails project)?
Thank you so much!
You can add constraints to command classes. If a command class is in the same .groovy file as a controller (in Groovy you can have more than one public class in each .groovy file), you don't need to do anything special for Grails to recongise it as a command class.
However, if your command class is somewhere else (e.g. under src/groovy), you need to annotate it with #Validateable and add the package name to the grails.validateable.packages parameter in Config.groovy. Here's an example of a command that's not in the same file as a controller
pacakge com.example.command
#Validateable
class Person {
Integer age
String name
static constraints = {
name(blank: false)
age(size 0..100)
}
}
Add the following to Config.groovy
grails.validateable.packages = ['com.example.command']
Command classes have a validate() method added by Grails. After this method is called, any errors will be available in the errors property (as per domain classes).
Using a grails Command Object is probably your best bet. It has constraints and validation, but no database backing. It's normally a value object that controllers use, but you could instantiate one outside of a controller without any problems.
Not sure if this is relevant to your use (I am not familiar with DTOs), but in the current version (2.3.8), you can also add Grails constraints to an abstract class, and they will be inherited by the domains that extend it. Your IDE might not like it though ;)

How do I tell ReSharper that an attribute means that a method is used?

I'm playing with SpecFlow, and ReSharper thinks that my step definitions are unused (I guess because they're used via reflection):
[Binding]
public class StepDefinitions
{
// ...
[When(#"I press add")]
public void WhenIPressAdd() // R# thinks this is unused
{
_calculator.PressAdd();
}
// ...
}
How can I tell ReSharper that methods with [Given], [When], [Then] attributes (etc.) are actually used? I don't want to use // ReSharper disable UnusedMember.Global comments.
I could also mark each method (or the whole class) with [JetBrains.Annotations.UsedImplicitly]. I don't particularly want to do that either.
You need to use JetBrains Annotations, and mark the attribute with an MeansImplicitUseAttribute. You can either reference JetBrains.Annotations.dll directly, or you can copy the annotations source code (from ReSharper / Options / Code Inspection / Code Annotations) into your solution.
If you need to annotate some external assembly you don't own, you need to create an External Annotation file (xml) in the following folder: %ReSharperInstallDir%\Bin\ExternalAnnotations. There are plenty of examples, you can just copy some.
The external annotations file can also be in the same path as the DLL if you name it DllNameWithoutExtension.ExternalAnnotations.xml.
There are plenty of examples, but I wanted to be a little more explicit in case you don't want to track down an example. :)
Create a file with the name of the attribute's assembly (.xml) in %ReSharperInstallDir%\Bin\ExternalAnnotations. For example, I made Microsoft.VisualStudio.QualityTools.CodedUITestFramework.xml and put this XML inside it:
<assembly name="Microsoft.VisualStudio.QualityTools.CodedUITestFramework">
<member name="T:Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute">
<attribute ctor="M:JetBrains.Annotations.MeansImplicitUseAttribute.#ctor" />
</member>
</assembly>
Restart VS and you're on your way!
these answers have helped but note worthy if you are looking to decorate an interface you will want to use the UsedImplicitly attribute
[UsedImplicitly]
public interface ISomeInterface
{
//... stuff
}

Resources