Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot test @Transactional not saving

I'am trying to do a simple Integration test using Spring Boot Test in order to test the e2e use case. My test does not work because I'am not able to make the repository saving data, I think I have a problem with spring contexts ...

This is my Entity:

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    @Id
    private int id;
    private String name;
}

This is the Person repository:

@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
}

The Person service:

@Service
public class PersonService {

    @Autowired
    private PersonRepository repository;

    public Person createPerson(int id,String name) {
       return repository.save(new Person(id, name));
    }

    public List<Person> getPersons() {
      return repository.findAll();
    }
}

The Person Controller:

@RequestMapping
@RestController
public class PersonController {

  @Autowired
  private PersonService personService;

  @RequestMapping("/persons")
  public List<Person> getPersons() {
      return personService.getPersons();
  }

}

The main Application class:

@SpringBootApplication
public class BootIntegrationTestApplication {

  public static void main(String[] args) {
    SpringApplication.run(BootIntegrationTestApplication.class, args);
  }
}

The application.properties file:

spring.datasource.url= jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true

And the Test:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class BootIntegrationTestApplicationTests {

    @Autowired
    private PersonService personService;
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    @Transactional
    public void contextLoads() {
        Person person = personService.createPerson(1, "person1");
        Assert.assertNotNull(person);

        ResponseEntity<Person[]> persons = restTemplate.getForEntity("/persons", Person[].class);
    }
}

The test does not work, because the service is not saving the Person entity .... Thanks in advance

like image 772
Hedi Ayed Avatar asked Apr 27 '17 13:04

Hedi Ayed


People also ask

How do you check if @transactional is working?

You can check if transaction is active using TransactionSynchronizationManager. isActualTransactionActive() . But you should call it before a service method executing. TransactionStatus status = TransactionAspectSupport.

What happens if we dont use @transactional?

Another problem with using @Transactional is that you can't use the database to investigate the failure reasons, as the data is never actually saved into the database because transactions are always rollback'd at the end of the test method execution.

Is @transactional required in Spring boot?

However, if we put the annotation on a private or protected method, Spring will ignore it without an error. Usually it's not recommended to set @Transactional on the interface; however, it is acceptable for cases like @Repository with Spring Data.

What is @transactional annotation in Spring Boot?

This page will walk through Spring @Transactional annotation example. 1. The @Transactional annotation describes a transaction attribute on an individual method or on a class. The @Transactional belongs to following package. 2.

What is testentitymanager in Spring Boot?

The Spring Boot TestEntityManager is an alternative to the standard JPA EntityManager that provides methods commonly used when writing tests. EmployeeRepository is the component that we are going to test. Now let's write our first test case:

What is integration testing in Spring Boot?

Integration Testing With @SpringBootTest As the name suggests, integration tests focus on integrating different layers of the application. That also means no mocking is involved. Ideally, we should keep the integration tests separated from the unit tests and should not run along with the unit tests.

What is the Spring Boot starter test dependency?

The spring-boot-starter-test is the primary dependency that contains the majority of elements required for our tests. The H2 DB is our in-memory database. It eliminates the need for configuring and starting an actual database for test purposes.


1 Answers

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class SmokeTest {

    @Autowired
    UserController userController;

    @Autowired
    UserDao userDAO;

    @Rollback(false) // This is key to avoid rollback.
    @Test   
    public void contextLoads() throws Exception {
        System.out.println("Hiren");

        System.out.println("started");
        userDAO.save(new User("tyx", "[email protected]"));
    }
}

Refer @Rollback(false) is key to avoid rollback.

like image 71
user2758406 Avatar answered Sep 20 '22 10:09

user2758406