unit testing a method called from another class - java

I am new to Android unit testing and I am using Mockito to do it.
I want to test my method which has a method from another class. I want to stub that method so that it should not be called. I am using doReturn().when() so that original method is not called but it is calling the original method.
Here is my code:
doReturn(true).when(myclass1mock).methodofclass1();
boolean a = myclass1mock.methodofclass1(); //here it return true
class2spy.methodofclass2(anyvalue);
The method I am testing is:
public class2 {
public void methodofclass2(Value) {
boolean value = class1.methodofclass1(); //here I don't want to call this method
}
}
The problem is method of class1 is called everytime. I want something so that class1.methodofclass1() is not called.
I am injecting using:
#Mock
class1 myclass1mock;
#InjectMocks
class2 myclass2;
#Before
public void setUp() {
myclass2 = new myclass2();
class2spy = Mockito.spy(myclass2);
}

As you want to test the behavior of Class2, then i think you mixed up the annotations. Also i would take advantage of #Spy annotations rather that configuring it by hand:
#Spy
class1 myclass1Spy;
#InjectMocks
class2 myclass2;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
Also, do not try not to spy the class which is being under test (class2). Use the real implementation.

Related

Unit testing a method of a class that has a constructor and an autowired field that needs to be mocked using mockito

I have a service class that extends another service with a constructor. This class has an autowired field and a method that I wanted to unit test using Mockito. However, I am having trouble writing a unit for it.
Let say the service looks somewhat like this:
#Service
public class SomeService extends Service {
#Autowired
private SomeClient someClient;
public SomeService(Product product, #Qualifier(Constants.SOME_BEAN) Details temp) {
super(product, temp);
}
#Override
public State create() {
Request request = new Request();
request.set...
request.set..
Status status = someClient.createTenant(request);
..
.. // construct a State object and return
}
}
Now, I am writing a test for this class and I am trying to unit test the method create() above. I am having trouble mocking someClient there when this method is called by my test.
The test class looks somewhat like:
#RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {
private Detail temp;
private SomeFacade service;
private SomeClient someClient;
private Product product;
#Before
public void setup() {
temp = mock(Details.class);
product = mock(Product.class);
service = spy(new SomeService(product, temp));
someClient = mock(SomeClient.class);
}
#Test
public void test() {
Status status = new Status();
status.setStatus(...);
when(someClient.createTenant(any())).thenReturn(status);
State state = service.create();
// asserts
}
}
What I want to is that when I call service.create in the test above, the call
someClient.createTenant(request); in the method tested should be mocked to return a value and this is something I am not able to get working. Any help?
We can use Mockito's #InjectMocks-annotation to inject mocks into our unit under test. For this, we also need to
remove mock intialization from the setup()-method and
annotate the mocks with #Mock
Remarks:
Instead of field injection, I would recommend constructor injection. This allows, among other things, to keep the structure of the code and create the unit under test within setup() by manual injection
I would also recommend to add a type to the when: when(someClient.createTennant(any(Request.class)))...
As was pointed out by #second, the spy on the unit under test is superfluous.
Also pointed out by #second was the fact that field injection will not work if a constructor is present

Mockito Not Able to Mock function call present in target class's constructor

I am trying to test the following class using Mockito and JUnit :
public class A {
private SomeClass someObject;
private SomeImpClass someImpObject1;
private SomeImpClass2 someImpObject2;
public A(SomeImpClass someImpObject1, SomeImpClass2 someImpObject2){
someObject = makeNewObject(someImpObject1, someImpObject2);
}
public makeNewObject(SomeImpClass1 someImpObject1, SomeImpClass2 someImpObject2){
return new SomeObject(someImpObject1,someImpObject2);
}
public usingSomeObject(){
someObject.doSomething();
}
}
So, I wrote a Unit Test using Mockito and JUnit :
#RunWith(MockitoJUnitRunner.class)
public class ATest {
#Mock
SomeImpClass1 someImpObject1;
#Mock
SomeImpClass2 someImpObject2;
#Mock
SomeObject someObject;
#Spy
A a;
#Before
public void setUp() {
when(A.makeNewObject).thenReturn(someObject);
this.A = new A(this.someImpObject1, someImpObject2);
when(someObject.doSomething).thenReturn(something);
}
}
The Issue I am facing here is, although I have stubbed the function makeNewObject to return a Mocked object of SomeClass, the code flow is still going inside the fucntion (makeNewObject) and giving a null exception.
What Am I Doing Wrong ?
I have wasted a day behind this.
Not Very Fluent with Mockito.
You wont be able to achieve what you are aiming for with spying and stubbing.
This is because your aiming at stubbing a method used in a constructor.. but you cannot start stubbing once you created a concrete object and spy it.. can't be done..
I would suggest creating a private class inside the test class which extends your class under test, override the method invoked in the constructor and then use it in your tests:
#RunWith(MockitoJUnitRunner.class)
public class ATest {
#Mock
SomeObject someObjectMock;
A a;
#Before
public void setUp() {
this.a = new MyTest();
}
private class MyTest extends ATest{
#Override
public makeNewObject(SomeImpClass1 someImpObject1, SomeImpClass2 someImpObject2){
return someObjectMock;
}
}
Now you dont need to use spying and stubbing of it also as the overriden method is always returning what you expect in the test.

Mockito issue with List

I have a DAO method which returns a List.
Now I am trying to mock this DAO class in my service layer but when I invoke the DAO method, it is giving me a empty even though I have mocked the DAO method
Below is the sample code snippet,
public class ABCTest {
#InjectMocks
ABC abc = new ABC();
#Mock
private ABCDao dao;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
dao = Mockito.mock(ABCDao.class);
Mockito.when(dao.getListFromDB()).thenReturn(Arrays.asList("1","2","3"));
}
#Test
public void testServiceMethod() {
abc.serviceMethod(); // Inside this method when the DAO method is called, it is giving me an empty list even though I have mocked it above.
}
Any pointers would be helpful
Don't use MockitoAnnotations.initMocks(this); use #RunWith(MockitoJunitRunner.class) instead
You are calling dao = Mockito.mock(ABCDao.class) which overrides the dao created by MockitoAnnotations.initMocks(this)
the ABCDao instance inside ABC is now different to the dao member of your test case.
I can only assume that the following would fail:
assertTrue(dao == abc.getDao())
Solution: Remove the following line
dao = Mockito.mock(ABCDao.class);

How to create a dummy instance unsing jmockit?

For a test I like to create a new instance of ComplicatedClass . In reality it's very complicated to crate this instance, but I don't need the real constructor to run nor any of it's data. All I need is an object of ComplicatedClass. How can I do that?
public class ComplicatedClass {
public ComplicatedClass(/* lots of dependencies */) {
}
}
#Test
public class SomeTest {
public void test1() {
ComplicatedClass complicatedInstance = /* new ComplicatedClass(); /*
AnotherClass ac = new AnotherClass(complicatedInstance);
/* ... */
}
}
#Tested annotation does this:
#Tested ComplicatedClass complicatedInstance;
That's it. Please note that the above won't do any mocking. It is just convenient way of creating instances without calling consturctors, etc.
If you want ComplicatedClass to be mocked, use #Mocked annotation:
#Mocked ComplicatedClass complicatedInstance;
In this case, you also get your instance automatically created, but the instance is mocked.
#Tested internally instantiates the class object.
But in case of Junit test case writing of singleton class how #Tested internally creates instance because for singleton private constructor is there.

Doubts with mockito

I have a doubt with Mockito.
I would want to test this simple class:
public class MyClass{
private UserService userService;
public void deleteUser(){
userService.getAdminUser(1);
userService.deleteUser(0);
}
}
I wrote this simple test:
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
#MockitoAnnotations.Mock
private UserService userService;
#Test
public void test(){
MyClass myClass=new MyClass();
myClass.userService=userService;
myClass.deleteUser();
}
}
This test run with no errors.
I await that it didn't compile because there isn't any call to userService method..
Mocks created by Mockito are "smart". They don't do anything when a void method is called. They return null when a method returning an object is called. They return an empty collection when a method returning a collection is called.
If you want to verify that getAdminUser() and deleteUser() have been called, use Mockito.verify().
These two things are explained in the Mockito documentation, points 1 and 2. In particular:
By default, for all methods that return value, mock returns null, an empty collection or appropriate primitive/primitive wrapper value (e.g: 0, false, ... for int/Integer, boolean/Boolean, ...).
you have not added any check to see if userService is used in any way. Adding a verify will do that for you: When to use Mockito.verify()?
I would advice you to read up on how Mockito works in tests, I think you have jumped past some of the fundamentals when it comes to learning the design and how method calls to the mock is treated.
Here is how you would test it with a different set of methods which invokes no annotations. Note that this is TestNG, but adapting it to JUnit 4+ is easy:
import static org.mockito.Mockito.*;
public final class Test
{
private UserService userService;
#BeforeMethod
public void init()
{
userService = mock(UserService.class);
}
#Test
{
final MyClass myClass = new MyClass();
myClass.userService = userService;
myClass.deleteUser();
verify(userService, times(1)).getAdminUser(1);
verify(userService, times(1)).deleteUser(0);
}
}
Note that there is a one-argument only verify() variant, which is exactly equivalent to having times(1) as the second argument. There is also never().
If for instance you wanted to test that the .deleteUser() method was not called with any argument, you'd do:
verify(userService, never()).deleteUser(anyInt());

Categories