JUnit Mockito object initialization in method - java

I am using Mockito's when and thenReturn function and am wondering if there's a way for the object inside to be initialized in the test functions. So for example if I had:
public class fooTest {
private Plane plane;
private Car car;
#Before
public void setUp() throws Exception {
Mockito.when(Car.findById(eq(plane.getId()))).thenReturn(plane);
}
#Test
public void isBlue() {
plane = new Plane();
plane.setId(2);
Plane result = Car.findById(car);
assertEquals(Color.BLUE, result.getColor());
}
}
Obviously the above code doesn't work because it throws a null pointer exception but the idea is to initialize the plane object in every test function and have mockito's when use that object. I suppose I could put the when line in every function after the Plane object has been initialized and set but that makes the code look very ugly. Is there a simpler way to do it?

Since I dont know your Plane or Car class, am going to make some assumptions in the test class.
I dont know what you are trying to test, If you are trying to test Car , you shouldnt ideally mock your class under test.
Any way you can do something like this in your setUp method.
public class fooTest {
private Plane plane;
#Mock
private Car car;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
plane = new Plane();
plane.setId(2);
plane.setColor(Color.BLUE);
Mockito.when(car.findById(eq(plane.getId()))).thenReturn(plane);
}
#Test
public void isBlue() {
// There is no point in testing car since the result is already mocked.
Plane result = car.findById(2);
assertEquals(Color.BLUE, result.getColor());
}
}

Related

Java MockedStatic method is still called

So I'm using MockedStatic<> to mock a static method but it seems like the item inside is still getting called? If this is the case, what's the point of mocking it? I have the following setup:
Object being tested:
public class ObjectBeingTested {
public void methodBeingTested() {
Object obj = ObjectInQuestion.getInstance(new Object(), "abc");
// do stuff with obj
}
}
The object with static method:
public class ObjectInQuestion {
public static ObjectInQuestion getInstance(Object obj, String blah) {
someLocalVar = new FileRequiredObject();
// we get NullPointerException here cuz in test env, no files found
}
private ObjectInQuestion() {
// private constructor to make people use getInstance
}
}
Test code:
public class MyTestClass {
MockedStatic<SomeClass> mySomeClass;
#Mock ObjectInQuestion mMockedObjectInQuestion;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
mySomeClass = mockStatic(SomeClass.class);
when(SomeClass.getInstance(any(), anyString()).thenReturn(mMockedObjectInQuestion);
}
#After
public void tearDown() {
mySomeClass.close();
}
}
My questions are the following:
Why calling ObjectInQuestion.getInstance() in the test class, it's totally fine but when it's being called from ObjectBeingTested, it runs the real construction?
I tried to use mockConstruction on FileRequiredObject, it still actually construct the object ... why?
You're using the wrong syntax for stubbing the static method. You want something like
mySomeClass.when(
()->SomeClass.getInstance(any(), anyString()))
.thenReturn(mMockedObjectInQuestion);
More information available here
Assuming MockedStatic<SomeClass> mySomeClass; is actually MockedStatic<ObjectInQuestion> mySomeClass;, I would try to simplify the setup using a classic try block.
In any case, sharing the actual test method might be able to shine some light. ;)

Skip null check in mockito

I am trying to write unit test cases for one of the methods in code.Below is the method
public boolean isValid() {
if(object == null)
return false
//do something here and return value.
}
The object is created by this method which is done before without getter setter method.
private Object returnObject() {
object = Axis2ConfigurationContextFactory.getConfigurationContext();
return object;
}
When I try to test isValid(), the object is always null, so it never goes in the code to do something.
I was checking if there is any way to skip that line or make the object not null. I also tried creating an object using returnObject method. But it uses Axis library classes which throws error if it does not find certain data. What can be done in this case? I am dealing with legacy code so any pointers would be helpful.
Edit : Adding test implementation.
#PowerMockIgnore({ "javax.xml.*", "org.w3c.dom.*", "javax.management.*" })
public class ClassTest {
private ClassTest classTestObj;
#BeforeMethod
public void callClassConstructor() {
classTestObj = //call class constructor
}
#BeforeClass
public void setUpClass() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public boolean isValidTest() {
Boolean result = classTestObj.isValid();
Assert.assertEquals(result);
}
}
As I mentioned in the before comment, you can make use of MockedStatic to mock the static method - https://javadoc.io/static/org.mockito/mockito-core/4.4.0/org/mockito/Mockito.html#static_mocks
So your code will somewhat look like the below one if you are making use of Mockito instead of PowerMockito.
#RunWith(MockitoJUnitRunner.class)
public class ClassTest
{
#Mock
private Object mockAxis2ConfigurationContextFactoryObject;
#Test
public boolean isValidTest() {
try (MockedStatic<Axis2ConfigurationContextFactory> mockedStatic = mockStatic(Axis2ConfigurationContextFactory.class)) {
mockedStatic.when(()->Axis2ConfigurationContextFactory.getConfigurationContext()).thenReturn(mockAxis2ConfigurationContextFactoryObject);
Boolean result = classTestObj.isValid();
Assert.assertEquals(result);
}
}

Mock method drawn to interface for searching null

I have an method which i must drawn to interface and write test for searching nullPointerExc. Here is the method:
boolean hasDocsChangedRequired (GroupProvider currentGroupAdm, GroupProvider groupAdm) {
return !currentGroupAdm.getDocs().equals(groupAdm.getDocs());
}
Somewhere in getDocs method is null.
I created the interface Changer with method:
boolean hasDocsChangedRequired();
And I implement this to class with the same body method as previously with SOLID rules
I have question how to good write test using mockito to fully cover this boolean function?
#pawel you can write test for checking your function like this, i am assuming that function is not static.
If you want to make it static , then you simply have to remove these 2 lines
#InjectMocks
ChangerImpl changer;
And in place of "changer" you have call corresponding Implemented class.
Hope this helps.
#RunWith(MockitoJUnitRunner.class)
public class TestSampleTest {
#InjectMocks
ChangerImpl changer;
#Test(expected = NullPointerException.class)
public void test1(){
GroupProvider currentGroupAdm = mock(GroupProvider.class);
doReturn(null).when(currentGroupAdm).getDocs();
GroupProvider groupAdm = mock(GroupProvider.class);
oReturn("sample2").when(groupAdm).getDocs();
changer.hasDocsChangedRequired(currentGroupAdm, groupAdm);
}
#Test
public void test2(){
GroupProvider currentGroupAdm = mock(GroupProvider.class);
doReturn("sample1").when(currentGroupAdm).getDocs();
GroupProvider groupAdm = mock(GroupProvider.class);
doReturn("sample2").when(groupAdm).getDocs();
Assert.assertThat(changer.hasDocsChangedRequired(currentGroupAdm, groupAdm), is(true));
}
#Test
public void test3(){
GroupProvider currentGroupAdm = mock(GroupProvider.class);
doReturn("sample1").when(currentGroupAdm).getDocs();
GroupProvider groupAdm = mock(GroupProvider.class);
doReturn("sample1").when(groupAdm).getDocs();
Assert.assertThat(changer.hasDocsChangedRequired(currentGroupAdm, groupAdm), is(false));
}
}
The output of your method
boolean hasDocsChangedRequired (GroupProvider currentGroupAdm, GroupProvider groupAdm) {
return !currentGroupAdm.getDocs().equals(groupAdm.getDocs());
}
solely depends on your two input objects.
In other words: you only have to provide input objects that give what you want to give for a specific test. Meaning: you probably want to write a test where currentGroupAdm.getDocs() gives something that is equal to groupAdm.getDocs(), and one where the two calls give a non-equal result.
Ideally, you don't need to mock anything here.

is there any way in Mockito I set a rule to return a value when a property of a specific object type is called?

I am trying to do the follow (Im sure there is a way, but I cant figure it out).
The problem:
There is a private method in my class, the class was injected using #InjectedMocks.
The private method calls a service and sends as parameter a property from a privated object.
Something like this
private MyObject myObject = new Object();
public void main(){
doSomething();
}
private void doSomething(){
someService(mObject.getValue);
}
The problem is that my object is not that easy and it has an annotation that gives it the value. Seems like with #InjectedMocks the value is never assigned and myObject is always null.
Since both the method and the object are private I cannot just assign the value (And I am avoiding add public setters for them).
My approach:
I want to mock something like this:
when(any(MyObject).class).getValue().thenReturn("something");
So, I will avoid NP at my test.
Is it possible using mockito?
Is there any more elegant way to do this??
I assume that you have some errors in your code example.
The following actually works and prints "foobar": try to compare it with your actual code to see what you forgot.
public class MockitoTest {
#InjectMocks private TestClass test;
#Mock private MyObject mock;
#Test
public void test() {
MockitoAnnotations.initMocks(this);
Mockito.when(mock.getValue()).thenReturn("foobar");
test.main();
}
}
class TestClass {
private MyObject myObject = new MyObject();
public void main() {
doSomething();
}
private void doSomething() {
System.out.println(myObject.getValue());
}
}
class MyObject {
public String getValue() {
return "hello";
}
}
You can mock the object or the method alone using PowerMock.createPartialMock and the proxy the method call.
For example your above code
when(any(MyObject).class).getValue().thenReturn("something");
should be
when(mockedObject).methodCall().thenReturn("something");

How should I mock out a single method inside an object I'm trying to test?

I have a problem with a class that I am testing where in almost every method I want to test, one of the first things each method does is call this one specific method. This method that is called once by all of these other methods takes a long time to execute. I don't want to have to wait for this every time I run my tests, it really is just a huge waste of time.
I attempted to #Spy the method using Mocktio, but I ran into problems because the really long method doesn't return anything. Can someone suggest a good way to mock out a single method inside a class I am trying to test?
Example:
public class myClass {
public void methodOne() {
reallyLongMethod();
// More code
}
public void methodTwo() {
reallyLongMethod();
// More code
}
.
.
.
public void methodN() {
reallyLongMethod();
// More code
}
public void reallyLongMethod() {
}
}
This is the class I am trying to test. I want to test all of the 'methodX()' methods. I don't want to run reallyLongMethod everysingle time however.
So, is there a way to use Mockito 'Spy' to stub out reallyLongMethod()? Even though it doesn'treturn anything?
You can use a Spy with doNothing(), but make sure you use the spy during the test. Mockito spies copy the original, instead of delegating to it.
#RunWith(MockitoJUnitRunner.class)
public class YourTest {
// Option 1:
// #Spy MyClass myClass = new MyClass();
// Option 2 (see #Before method)
MyClass myClass;
#Before public void ignoreReallyLongMethod() {
myClass = spy(new MyClass()); // discard original
doNothing().when(myClass).reallyLongMethod();
}
#Test public void methodOneWorks() {
myClass.methodOne(); // you're using the spy here
assertEquals(42, myClass.getFoo());
}
}
Though this does evoke a code smell, don't mock or stub the class under test, as long as you're careful to test the method behavior (methodOne) and not the stubbed behavior (reallyLongMethod) you'll be good to go. If you do want to test reallyLongMethod you'll want to use a different object instance or else you'll "test" the doNothing() call alone. Do bear in mind that if reallyLongMethod and your other methods have any negative interactions, these tests won't tell you about that.
By the way, you can also do the equivalent without using Mockito, which may make a little clearer what you are or aren't doing with your mocks:
#RunWith(JUnit4.class)
public class YourTest {
MyClass myClass;
#Before public void createMyClass() {
myClass = new MyClass() { // create an anonymous inner class
#Override public void reallyLongMethod() {} // that does nothing here
};
}
}

Categories

Resources