0

I'm writing test for rest app in spring boot.

But in my test, interface CategoryService in CategoryController cannot be autowired when running test and NullPointerException raised.

CategoryService is injected at field level.

Here my classes:

CategoryController

@RestController
@RequestMapping("/v1/categories")
public class CategoryController {

    @Autowired
    private CategoryService categoryService;

    @RequestMapping
    public List<Category> getAll() {
        return categoryService.findAll();
    }
}

CategoryService

@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    CategoryRepository categoryRepository;

    @Override
    public List<Category> findAll() {
        return categoryRepository.findAll();
    }
}

CategoryRepositoryImpl

@Repository
public class CategoryRepositoryImpl  implements CategoryRepository {
    @Override
    public List<Category> findAll() {
        ... 
    }

}

----- TEST ------

AppTestConfig

@Configuration
public class AppTestConfig {

    @Bean
    public CategoryRepository categoryRepository() {
        return new TestCategoryRepository();
    }

    @Bean
    public CategoryService categoryService() {
        return new App.CategoryServiceImpl(); 
    }
}

CategoryControllerTest

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes =  {AppTestConfig.class})
public class CategoryControllerTest {

    @Autowired
    private CategoryRepository categoryRepository;

    @Test
    public void testGetAll() throws Exception {
        CategoryController controller = new CategoryController();
        List<Category> categories = controller.getAll();
        assertEquals(categoryRepository.findAll().size(), categories.size());
    }
}

With constructor injection, everything works fine.

What's the problem?

Teimuraz
  • 8,795
  • 5
  • 35
  • 62

2 Answers2

3

You are constructing the CategoryController by using the new keyword. In this way, spring doesn't know this object, therefore it can't inject anything into it.

The bean should by instantiated by spring, just like the CategorService, the object under test can be setup in the spring Configuration class.

If spring creates the bean, it will autowire the relevant properties.

@Autowired
private CategoryController underTest;
burna
  • 2,932
  • 18
  • 27
0

It's hard to know without seeing the whole project, but please try adding some more annotations :-) :

  1. @ComponentScan on AppTestConfig - to ensure that all beans are available
  2. @SpringApplicationConfiguration instead of @ContextConfiguration - I think this is always the case for Spring Boot
  3. @WebAppConfiguration on CategoryControllerTest - Web App context may be needed for servlets if you are using Spring MVC.
S.D.
  • 111
  • 3