I have a class where I autowired it using lazy initialization in constructor. But Iam unable to mock it using #Mock. It throws null pointer exception in my test class.
#Transactional
#Repository
public class A{
private B b;
#Autowired
public A(#Lazy B b {
this.b= b;
}
}
Iam unable to mock the bean B.My test class is as follows.
#RunWith(MockitoJUnitRunner.class)
public class ATest{
#Rule
public ExpectedException thrown = ExpectedException.none();
#InjectMocks
A a;
#Mock
B b;
Mockito.when(b.methodCall()).thenReturn("test");
}
The above code returns null pointer exception as Iam unable to mock class B.Please let me know how to mock this.
You are using constructor injection with #Autowired and #Lazy annotation should be at the place above the method. Please try :
Class A :
#Transactional
#Repository
public class A {
private B b;
#Autowired
#Lazy
public A(B b) {
this.b = b;
}
}
Class B :
#Component
public class B {
public String methodCall() {
return "foo";
}
}
Test class:
#RunWith(MockitoJUnitRunner.class)
public class MyTest {
#InjectMocks
private A a;
#Mock
private B b;
#Before
public void before() {
Mockito.when(b.methodCall()).thenReturn("test");
}
#Test
public void myTest() {
assertEquals(b.methodCall(), "test");
}
}
I am pretty sure it is not the best solution but I resolved it using reflection
#Before
public void before() {
ReflectionUtils.setField(ReflectionUtils.findRequiredField(A.class, "b"), a, b);
}
Related
#Component
public class car {
void getCar(){
System.out.println("Honda");
}
}
public class Tyre {
#Autowired
private car cars;
#Test
void print(){
cars.getCar();
}
}
java.lang.NullPointerException when "cars.getcar" is called
Spring Version 2.7.1
I am trying to annotate an autowire for Car.class
but it returns null on run time
Attached the project Structure
add #SpringBootTest on top of the test class.
#SpringBootTest
public class Tyre {
#Autowired
private car cars;
#Test
void print(){
cars.getCar();
}
I have class A having structure:
#Service
Class A implements AInterface {
private final C c;
String test(String b) {
}
}
Structure of class C:
class C {
// some methods
}
then I wrote interceptor for this class :
#Aspect
#Component
class Interceptor {
#Around(
value =
"execution(* AInterface.test(..)) && args(c)")
public Object intercept(ProceedingJoinPoint joinPoint, String c) {
// some logic
}
}
I am trying to do integration test and wants to inject mock class c in A but its not happening.
Test class structure:
#SpringBootTest
class ATest {
// Tried #MockBean also
#Mock
private C c;
#Autowired #InjectMock private AInterface a;
#BeforeTest {
MockitoAnnotations.initMocks(this);
// tried using ReflectionUtils to inject mock
}
#Test
void testTest () {
// when then logic
}
}
Here is the code I am using.
The test class:
#ExtendWith(MockitoExtension.class)
#SpringBootTest
public class XTest{
#Mock
XRepository xRepository ;
#Mock
XServiceImpl xServiceImpl ;
X x = new X();
XC xC= new XC();
List<X> lX= new ArrayList<X>();
#BeforeEach
void createProcedure(){
x.setId((long)1);
x.setDescription("First one");
x.setValue("10");
xC.setCode("X");
x.setCategory(xC);
lX.add(x);
}
#Test
void testGetXByCode() {
Mockito.when(xRepository.findByCode(Mockito.anyString())).thenReturn(lX);
List<X> xL= xServiceImpl.getProcedureByCode("X");
System.out.println(lX.size());
assertEquals(1,xL.size());
assertNotEquals("Y", xL.get(0).getCategory().getCode() );
}
}
My service implementation class:
#Service
public class XServiceImpl implements XService {
private final XRepository xRepository;
#Autowired
public XServiceImpl(XRepository xRepository) {
this.xRepository = xRepository;
}
#Transactional
public List<X> getXByCode(String code) {
List<X> x= new ArrayList<>();
try {
x= xRepository.findByCode(code);
if (!x.isEmpty()) {
return x;
}
} catch (Exception ex) {
}
return null;
}
}
And my repository code is as follows:
#Repository
public interface XRepository extends JpaRepository<X, Long>{
public Optional<X> findById(Long id);
}
Both the test cases seem to be failing. Can anyone help me out with this?
The actual size of the list is 1 which is being printed. But when then return doesn't seem to be returning the same one.
#Mock creates mock. You should annotate XServiceImpl with #InjectMocks so that creates an instance of the class and injects the mocks that are created with the #Mock annotations (such as XRepository).
#InjectMocks
XServiceImpl xServiceImpl;
I have a class:
#Component
public class B {
#Autowired
private A a;
}
and A is a component:
#Component
public class A{}
In unit test class BTest:
public class BTest {
#Test
public void testBMethod() {
}
}
I am not using an xml to define context or for beans to be picked from.
What is the cleanest way I can get the test to run?
You don't have to use Spring for the unit tests. Mockito may be used for this.
public class BTest {
#Mock
private A a;
#Mock
private B b;
#Test
public void testBMethod() {
}
}
For more details, you may check https://springframework.guru/mocking-unit-tests-mockito/
and https://dzone.com/articles/use-mockito-mock-autowired
I've been learning more about the Mockito framework within Java and I'm lost about what to do to complete this unit test.
Basically, the error from the console states that there is a NullPointerException when the Bar.sayHi() method is trying to be run from the Foo test. I suspect it has something to do with the autowired fields (but I maybe wrong)?
Below is a simple example of the problem that I'm running into:
#RunWith(MockitoJUnitRunner.class)
public class FooTest {
#Mock
//#Spy // Cannot spy on an interface
IBar bar;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
// Given
FooImpl foo = new FooImpl();
foo.saySaySay();
// When
// Then
}
}
Here's the FooImpl class under testing (there's an interface for Foo):
public class FooImpl implements IFoo {
#Autowired
private IBar bar;
public void saySaySay() {
bar.sayHi();
}
}
And the Bar class (there's also an interface for Bar):
public class BarImpl implements IBar {
#Override
public void sayHi() {
System.out.println("hello");
}
}
Does anyone has a suggestion on this? Thanks.
Just creating a mock of Ibar will not inject that mock into the #Autowired field.
Autowiring is the job of Spring, not Mockito.
You need to explicitly tell mockito to inject those into testing objects using #InjectMock
#RunWith(MockitoJUnitRunner.class)
public class FooTest {
#InjectMocks
FooImpl foo;
#Mock
IBar bar;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
foo.saySaySay();
}
}
or manual set the mock object inside the tested object.
#Test
public void test() {
FooImpl foo = new FooImpl();
ReflectionTestUtils.setField(foo, "bar", bar);
foo.saySaySay();
}
RunWith(MockitoJUnitRunner.class)
public class FooTest {
#Mock
//#Spy // Cannot spy on an interface
IBar bar;
#InjectMocks
private FooImpl foo;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
// Given
foo.saySaySay();
verify(bar).sayHi();
// When
// Then
}
}