autowired #components null in unit test - spring

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

Related

Mockito: How to properly mock a List of Spring Services

I have the following Spring Service class that I'm trying to test with Mockito:
#Service
public class ObjectExportService {
#Autowired
protected List<SecuredService<? extends SecuredObject>> securedServices;
public void doStuff() {
for(int i = 0; i < this.securedServices.size(); i++){
SecuredService<? extends SecuredObject> securedSrv = this.securedServices.get(i);
//this access works
}
for (SecuredService<? extends SecuredObject> securedSrv : this.securedServices) { //this access does not work
}
}
}
This is my Test class for that service:
#RunWith(MockitoJUnitRunner.class)
public class ObjectExportServiceTest {
#InjectMocks
private ObjectExportService objectExportService;
#Mock
protected List<SecuredService<? extends SecuredObject>> securedServices;
#Test
public void testDoStuff(){
objectExportService.doStuff();
Assert.assertTrue(true);
}
}
When I run the test, I get a NullpointerException, but only in the for-each loop.
First I assumed is a similar problem as described in this thread:
I have Mocked the List and would therefore need to mock the iterator() call.
The solutions provided in that thread didn't work for me, because I am actually autowiring a List.
So I stumbled across this solution in another thread. Simply changing the #Mock to #Spy resolved the issue for me:
#RunWith(MockitoJUnitRunner.class)
public class ObjectExportServiceTest {
#InjectMocks
private ObjectExportService objectExportService;
#Spy // <-- change here
protected List<SecuredService<? extends SecuredObject>> securedServices;
#Test
public void testDoStuff(){
objectExportService.doStuff();
Assert.assertTrue(true);
}
}

Spring AOPed target class not injecting mocks

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
}
}

How to mock lazy initialized Bean using Junit Mockito

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);
}

How to Pass #Value to a #Component for Spring Unit Testing

Im writing unit tests for services, controllers, etc however theres is a #Component that has the following values
#Component
Public class myclass
#Autowired
Private MyTemplate myTemplate
#Value("$someString")
Private String someString
#PostConstruct
Public void loadString()
...
How would I manually load values into the #Values? I have tried with Mocks, TestPropertySource, ReflectionTestUtils, among other ways found around
You can inject the #Value in test class by ReflectionTestUtils. Load container only in case of Controllers. For writing test cases for services and dao you don't need to load the spring container.
public class TestClass{
private #InjectsMock ServiceClass service;
#BeforeAll
public void setUp(){
ReflectionTestUtils.setField(service, "someString", "someValue");
}
//your test cases over here.
}
I can immediately think of two options
1) You could define $someString in your test/resources/test.properties
#RunWith(SpringRunner.class)
#TestPropertySource(locations="classpath:test.properties")
public class ClassTest {
}
2) do it manually
#RunWith(SpringRunner.class)
public class ClassTest {
#Autowired
private MyClass miclass;
#Before
public void setupObject() {
miclass.setProperty("someting");
}
}

Mockito - Spring unit tests

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
}
}

Resources