Spring Boot Unit Testing - Test fails complaining about not having an "entityManagerFactory" bean defined

spring boot rest controller unit test example
spring boot test
datajpatest
spring boot rest controller unit test example using mockito
spring boot test mock service
spring boot h2 unit test
jpa unit test entitymanager
spring test configuration

I'm trying to write a unit test for a Controller in a Spring Boot application. The application runs smoothly, my problem is with running its tests.

Here is the test code:

@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
@AutoConfigureTestEntityManager
public class MyControllerTest {

@Autowired
private MockMvc mockMvc;

@Mock
private MyRepository myRepository;

@Mock
ZendeskNotifier zendeskNotifier;

@Mock
ActivityLogger activityLogger;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}

@Test
public void cannotSendFooWithoutMessageBody() throws Exception {
    this.mockMvc.perform(post("/api/v1/foo/1/send"))
            .andDo(print())
            .andExpect(status().is4xxClientError())
            .andExpect(content().string(containsString("The message body cannot be empty.")));
}
}

When I try running it I get:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field jobEventRepository in foo.bar.util.memsource.svc.MemsourceEventProcessor required a bean named 'entityManagerFactory' that could not be found.


Action:

Consider defining a bean named 'entityManagerFactory' in your configuration.

And that feels weird to me, since I'm providing the AutoConfigureTestEntityManager annotation and would expect all the EntityManager-related stuff to be in place.


If Google brought you here and you're using Spring Boot, you may need to add @DataJpaTest to your test class. It's found in org.springframework.boot:spring-boot-test-autoconfigure. You may also discover upon rerunning that you need to declare a dependency on org.hibernate:hibernate-validator.

Unit Testing with Spring Boot, If you have written tests with Spring or Spring Boot in the past, you'll This class cannot be unit tested without Spring because it provides no way to pass in a the compiler will complain if we have forgotten to initialize the field. Our test would now fail with a NullPointerException at assertThat(savedUser. Mockito and AssertJ are automatically imported with the spring-boot-starter-test dependency, but we’ll have to include Lombok ourselves. Don’t Use Spring in Unit Tests. If you have written tests with Spring or Spring Boot in the past, you’ll probably say that we don’t need Spring to write unit tests. Why is that?


Inject Spring's TestEntityManager in your mockito test class.

@Autowired
private TestEntityManager entityManager;

You are already using @AutoConfigureTestEntityManager on the test class to auto configure this test entity manager. So you don't have to do anything else in the config file.

Testing improvements in Spring Boot 1.4, The easiest way to unit test any Spring @Component is to not involve Spring at all! write components that use constructor injections as you no longer need to use @Autowired . that you can't use when running tests, or testing failure scenarios that are So HtmlUnit complains on valid JavaScript code. In this tutorial, we took a deep dive into the testing support in Spring Boot and showed how to write unit tests efficiently. The complete source code of this article can be found over on GitHub . The source code contains many more examples and various test cases.


Spring Boot is loading your application's configuration, causing your data layer to be initialized.

Excerpt from Spring Boot's docs, Detecting Test Configuration:

Spring Boot’s @*Test annotations search for your primary configuration automatically whenever you do not explicitly define one.

The search algorithm works up from the package that contains the test until it finds a class annotated with @SpringBootApplication or @SpringBootConfiguration. As long as you structured your code in a sensible way, your main configuration is usually found.

When the scanning hits your main class it is likely finding an annotation like @EnableJpaRepositories, which initializes your data layer and thus requires the entity manager factory. (You may see other side effects too, like Hibernate initializing your in-memory database if your application uses one.)

As other answers suggest, you could initialize the data layer, or try to wire/mock the missing beans. But since you aren't testing the data layer here it would be better to control the test's configuration.

The docs suggest some solutions:

  1. Move @EnableJpaRepositories from the main class to a config class in child package. It will get scanned by the application (from the top package down) but not by the unit tests. This is discussed in the section User Configuration and Slicing.

  2. Add a nested @Configuration class to override the configuration used by the unit test.

The first one seems like a good rule to follow in general. Other annotations like @EnableBatchProcessing and @EnableScheduling can be treated the same way, which will speed up your unit tests.

41. Testing, JUnit — The de-facto standard for unit testing Java applications. Spring Test & Spring Boot Test — Utilities and integration test support for Spring Boot Therefore, as long as your tests share the same configuration (no matter how it's​  In this second part of the series on testing with Spring Boot, we’re going to look at web controllers. First, we’re going to explore what a web controller actually does so that we can build tests that cover all of its responsibilities.


you need to configure entityManagerFactory, you can refer bellow code

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="org.demo.test.entity" />
<property name="dataSource" ref="dataSource" />

<property name="jpaProperties">
    <props>
        <prop key="hibernate.show_sql">true</prop>
        <prop key="hibernate.hbm2ddl.auto">create</prop>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    </props>
</property>

<property name="persistenceProvider">
    <bean class="org.hibernate.jpa.HibernatePersistenceProvider">
</bean>
</property>

</bean>

Spring Framework Reference Documentation, Make a local Java method an HTTP endpoint without having to deal with the The spring-test module supports the unit testing and integration testing of an IllegalStateException will be thrown complaining about an unknown bean scope. By default, the autowiring fails whenever zero candidate beans are available; the  By default, Spring boot uses Junit 4. To write tests in Junit 5, read this migration guide : Junit 5 with Spring boot 2. 1. Maven dependencies. Make sure to have spring-boot-starter-test dependency in the project to be able to execute unit tests.


Spring Boot - Tutorial, Without any further configuration it reloads the application every time you save a file in the project. injection you can write unit tests without any dependency on Spring. Besides testing support for Spring boot spring-boot-starter-test adds NONE: loads an ApplicationContext with no servlet environment. A common approach to unit testing is to mock external dependencies, for effectively testing the business logic. For example, a unit test could be run independent of a database. This ensures that tests do not have external dependencies and do not fail when something external to the test changes. Layer Integration Tests


Spring Boot Integration Testing Done The Right Way, This article will be about writing proper Integration Tests with Spring Boot 2. The only complaints we had: Sometimes we used a syntax which was Due to no database being there - it fails to connect to the database. by Emre Savcı How to test services, endpoints, and repositories in Spring Boot In this post I will show you how to write unit tests in spring boot applications. Why is it necessary to write unit test requires another article to explain. But for a brief explanation, I will tell you several things. I usually defend the argument that code without unit tests is dead code. Because, when a


Mockito assert no exception, This tutorial will help you learn how to write effective unit tests for your software with the is needed to make sure the test fails if the code does not throw an Exception your expect. some ideas about testing using the different tools given by Spring Boot Test dependency. Note: Does not complain if the collection is empty! Unit Testing is often underrated. As far as I am concerned, having good unit tests seperates good projects from bad. In this article, let's look at unit testing best practices in depth. We use examples from Java and JUnit to illustrate the concepts. However, the best practices are applicable irrespective of the programming language used.