How to mock super method call from mocked method
public class A extends B{
#Override
public retrieveData(){
//some action here
super.retrieveData();
}
}
abstract class B extends C{
//init super fields here
}
public class C{
public String retrieveData(){
//some return
}
}
Public Atest{
#InjectMock
A a;
#Mock
C parent; //also tryed for B but the same effect
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testDetailsRetrievePageList(){
when(parent.retrieveData()).thenReturn("stub");
String s = a.retrieveListData();
Assert.assertEquals("stub", s);
}
}
Didn't help Mockito How to mock only the call of a method of the superclass and post like that.
everytime my super is null in A class
Related
I have been searching for a while and I can't find a solution for this. I need to mock a class that is used in the #PostConstruct of another class. My classes are like this:
#Component
class A {
private final B b;
private String s;
public A(B b) {this.b = b;}
#PostConstruct
public void postConstruct() {
s = b.get().getString().toUpperCase();
}
}
#Component
class B {
private final C c;
public B(C c) {this.c = c;}
public C get() {return c;}
}
#Component
class C {
public C() throws Exception {throw new Exception();}
String getString() {return "C";}
}
Now I create the test that fails because the constructor of C fails:
#SpringBootTest
class DemoApplicationTests {
#Autowired A a;
#Test
public void canLoadContext() {
assertThat(a).isNotNull();
}
}
So I try to mock the C class:
#SpringBootTest
class DemoApplicationTests {
#MockBean
static C c;
#Autowired
A a;
#BeforeEach
public void beforeEach() {
when(c.getString())
.thenReturn("C_mocked");
}
#Test
public void canLoadContext() {
assertThat(a).isNotNull();
}
}
But this way it fails with a NPE in the line s = b.get().getString().toUpperCase(); because the C object in b is not the same that I have mocked with #MockBean. When getString() is called, it returns null and we get a NPE when calling .toUpperCase().
I have also tried to overwrite the mock like this:
#Configuration
#AutoConfigureBefore
static class TestContext {
#Primary
public C c() {
return when(mock(C.class).getString())
.thenReturn("C_mocked").getMock();
}
}
But in this case I get this error:
No qualifying bean of type 'com.example.demo.A' available: expected at
least 1 bean which qualifies as autowire candidate.
Could please somebody help out with this?
I don't know how to mark it as duplicate. But please take a look of this https://stackoverflow.com/a/58517289/11538031
The solution remains like this:
#Component
class A {
private final B b;
private String s;
public A(B b) {this.b = b;}
#PostConstruct
public void postConstruct() {
s = b.get().getString().toUpperCase();
}
}
#Component
class B {
private final C c;
public B(C c) {this.c = c;}
public C get() {return c;}
}
#Component
class C {
public C() throws Exception {throw new Exception();}
String getString() {return "C";}
}
#SpringBootTest
class DemoApplicationTests {
#Autowired
A a;
#Test
public void canLoadContext() {
assertThat(a).isNotNull();
}
#TestConfiguration
public static class TestContext {
#Bean
#Primary
public C c() {
return when(mock(C.class).getString())
.thenReturn("C_mocked").getMock();
}
}
}
I have this Interface:
public interface Test<T> {
default Class<?> getT() {
return T.getClass(); < --error
}
}
next i have a class that implements it:
static class ItemService implements Test<Item>{
}
And i want to get the 'Item' class from the 'ItemService' class
static ItemService service = new ItemService();
private static void k() {
System.out.println(service.getT());
}
Now one way to do it is this:
public interface Test<T> {
default Class<?> getT() {
return Type.type;
}
class Type {
public static Class<?> type;
}
}
Service:
static class ItemService implements Test<Item> {
public ItemService() {
Type.type = Item.class;
}
}
And it works fine but there is a problem,
When another class implement the interface:
static class OrderService implements Test<Order> {
public OrderService() {
Type.type = Order.class;
}
}
And i try:
static ItemService service = new ItemService();
static OrderService orderservice = new OrderService();
private static void k() {
System.out.println(service.getT());
}
I get the Order class and not the Item class
How can i make it work?
Classes inside interfaces are static, You can remove the default from the function and every class will need to implement this. example:
public interface Test<T> {
public Class<T> getT();
}
static class ItemService implements Test<Item> {
public Class<Item> getT() {return Item.class;}
}
static class OrderService implements Test<Order>{
public Class<Order> getT() {return Order.class;}
}
An alternative could be an abstract class.
public interface Test<T> {
public Class<T> getT();
}
abstract class AbstractTest<T> implements Test<T> {
private final Class<T> type;
AbstractItemService(Class<T> type) { this.type = type }
public Class<T> getT() {return type;}
}
class ItemService extends AbstractTest<Item> {
ItemService() { super(Item.class); }
// implement other things
}
class OrderService extends AbstractTest<Order>{
OrderService() { super(Order.class); }
// implement other things
}
Here is another option, if your implementation has an instance of T.
interface Test<T>{
T getT();
default Class<?> getClassOfT(){
return getT().getClass();
}
}
I have a POJO class:
#Data #Document
public class RoomPreferences{
private TypeEnum roomType;
private BigDecimal minLen;
private BigDecimal maxLen;
private List<BigDecimal> defaultPrices;
}
I want to populate a RoomPreferences object at test and I am using Mockito, but my RoomPreferences object's fields are always null.
public class TestingClass {
#Mock private RoomPreferences roomPreferences;
#InjectMocks public RoomServiceImpl roomService;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
when(roomPreferences.getMinLen()).thenReturn(BigDecimal.valueOf(10));
...
}
}
What I read out of this testing class:
public class TestingClass {
#Mock private RoomPreferences roomPreferences;
#InjectMocks public RoomServiceImpl roomService;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
when(roomPreferences.getMinLen()).thenReturn(BigDecimal.valueOf(10));
...
}
}
is that roomService of type RoomServiceImpl has an attribute of type RoomPreferences. And this attribute will be injected with the mocked object "roomPreferences".
The mocked object won't be populated with any value of the real class.
What you do is define what the mock should do when a method (as in the real class) is called on it:
when(roomPreferences.getMinLen()).thenReturn(BigDecimal.valueOf(10));
If you wan to assing a value to a property then don't mock the class and use the real class instead.
I am guessing that the problem you are facing is setting the RoomPreferences attribute in the roomService object. If that is the case you should add that class to the question.
Having the following classes :
public class A {
#Autowired
private Set<IClient> clients;
}
public class B implements IClient { }
public class C implements IClient { }
#RunWith(MockitoJUnitRunner.class)
public class Atest {
#InjectMocks
A a;
#Mock
IClient clients;
}
How I can use mocks for the Set of interfaces that will include both class B and C?
Use constructor injection insted of field injection, then create two mocks, put them in a set, and call your constructor with that set. For example:
public class Atest {
private A a;
#Mock
private IClient mockAClient;
#Mock
private IClient mockBClient;
#Before
public void prepare() {
a = new A(new HashSet<>(Arrays.asList(mockAClient, mockBClient));
}
}
I want the inherited getters in class A to return Mock of MyObject. How can I do that without directly stubbing getMyObject() method in A (i.e. via using some MockBase class) ?
public class Base {
#Autowired
private MyObject obj;
public MyObject getMyObject(){
return obj;
}
}
public class A extends Base {
#Autowired
private SomeObject xyz;
public void myMethod(){
MyObject obj = getMyObject();
//do something here
}
}
public void MockBase {
#Mock
protected MyObject obj;
public MyObject getMyObject(){
return obj;
}
}
public class ATest extends MockBase {
#InjectMocks
private A a;
#Mock
private SomeObject xyz;
#BeforeMethod
public void setUp(){
MockitoAnnotations.initMocks(this);
}
public void MyMethod_SomeCondition_ExpectedResult{
a.myMethod();
}
}
What's the issue there ? It's working as expected, maybe you ar using an older version of Mockito. For example with version 1.9.5 :
Heres's the parent of the class you want to test :
public class Base {
private BaseObjectDependency base_object_dependency;
public BaseObjectDependency getBase_object_dependency() {
return base_object_dependency;
}
}
Here's the class you want to test :
public class Child extends Base {
private ChildObjectDependency child_object_dependency;
public void myMethod() {
BaseObjectDependency obj = getBase_object_dependency();
//do something here
}
public ChildObjectDependency getChild_object_dependency() {
return child_object_dependency;
}
}
Here are the dependencies :
public class BaseObjectDependency { }
public class ChildObjectDependency { }
Now here's the parent class of the test :
import org.mockito.Mock;
public class MockBase {
#Mock protected BaseObjectDependency base_test_dependency_mock;
}
And finally the test :
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
public class ChildTest extends MockBase {
#InjectMocks private Child child;
#Mock private ChildObjectDependency child_test_dependency_mock;
#BeforeClass
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void check_that_mocks_are_correctly_injected() {
assertNotNull(child.getBase_object_dependency());
assertEquals(base_test_dependency_mock, child.getBase_object_dependency());
assertNotNull(child.getChild_object_dependency());
assertEquals(child_test_dependency_mock, child.getChild_object_dependency());
}
}
You'll see that nowhere I am stubbing getBase_object_dependency().