Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Autowired Bean is NULL in Spring Boot Unit Test

I am new to JUnit and automated testing and really want to get into automating my tests. This is a Spring Boot application. I have used Java Based Annotation style instead of XML based configuration.

I have a test class in which I'd like to test a method which retrieves a response based on a users' input.

Testing class:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SampleTest(){

  @Autowired
  private SampleClass sampleClass;

  @Test
  public void testInput(){

  String sampleInput = "hi";

  String actualResponse = sampleClass.retrieveResponse(sampleInput);

  assertEquals("You typed hi", actualResponse);

  }
}

Inside my "SampleClass" I have autowired a bean like this.

@Autowired
private OtherSampleClass sampleBean;

Inside my "OtherSampleClass" I have annotated a method like so:

@Bean(name = "sampleBean")
public void someMethod(){
....
}

The issue I'm having is when I try to run the test without the @RunWith and @SpringBootTest annotations when I try to run the test my variables annotated @Autowired are null. And when I try to run the test with those annotations RunWith & SpringBootTest then I get an

IllegalStateException caused by BeanCreationException: Error creating bean with name "sampleBean" AND failure to load application context caused by BeanInstantiationException.

The code works 'properly' when I try to use it as a user would so I can always test this way but I think automated tests would be good for the longevity of the program.

I have used the Spring Boot Testing Docs to assist me in this.

like image 214
alwaysStuckJava Avatar asked Jan 05 '18 12:01

alwaysStuckJava


People also ask

Why my Autowired Bean is null?

The field annotated @Autowired is null because Spring doesn't know about the copy of MileageFeeCalculator that you created with new and didn't know to autowire it.

Why Autowired is not working in Spring boot?

When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.

Can a bean be null?

Internal representation of a null bean instance, e.g. for a null value returned from FactoryBean. getObject() or from a factory method. Each such null bean is represented by a dedicated NullBean instance which are not equal to each other, uniquely differentiating each bean as returned from all variants of BeanFactory.

What will happen if I make @autowired as false?

By default, the @Autowired annotation implies that the dependency is required. This means an exception will be thrown when a dependency is not resolved. You can override that default behavior using the (required=false) option with @Autowired .


1 Answers

The following config works for me.

File: build.gradle

testCompile("junit:junit:4.12")
testCompile("org.springframework.boot:spring-boot-starter-test")

File: MYServiceTest.java

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest(classes = Application.class,
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@RunWith(SpringRunner.class)
public class MYServiceTest {

    @Autowired
    private MYService myService;

    @Test
    public void test_method() {
        myService.run();
    }
}
like image 188
Eddy Avatar answered Sep 17 '22 13:09

Eddy