10

Testing a Controller class when i try do to delete all records from my database via Spring's CrudRepository, but it seems like nothing is happening. It seems is not flushing by default.

I've never tried this repository in a real controller call in a browser just with Junit tests, but I think it would works fine! :)

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ActiveProfiles("test")
@Transactional
public class CostumerControllerIntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private CostumerService costumerService;

    private Costumer costumer;

    @Before
    public void before() {
        this.costumer = this.exampleBuilder();
        costumerService.saveAll(this.costumer);
    }

    @After
    public void after() {
        costumerService.deleteAll();
    }

    @Test
    public void Should_ReturnStandardError_When_NotFoundById() throws Exception {
        //implementation
    }


private Costumer exampleBuilder() {

    Costumer costumer = new Costumer("Test", "Test", "Test", CostumerType.LEGAL_PERSON);
    State state = new State("Example State");
    City city = new City("Example Sity", state);
    Address address = new Address("Example Address",
            "Example Address", "Example Address",
            "Example Address", city, costumer);

    costumer.getAddresses().add(address);

    return costumer;
}

}

@Service
@Transactional
public class CostumerService {

    @Autowired
    private CostumerRepository repository;

    public void deleteAll() {
        repository.deleteAll();
    }

   //another methods

}

The repository extending CrudRepository

@Repository
public interface CostumerRepository extends CrudRepository<Costumer, Integer> {

}

After enable to show sql hibernate.show_sql=true based on @TheCoder comment, the result is:

The deleteAll() on @After:

@After
public void after() {
    costumerService.deleteAll();
}

The output sql:

2019-02-27 06:07:06 - HHH000397: Using ASTQueryTranslatorFactory
Hibernate: 
    select
        costumer0_.id as id1_3_,
        costumer0_.cpf_cnpj as cpf_cnpj2_3_,
        costumer0_.email as email3_3_,
        costumer0_.name as name4_3_,
        costumer0_.type as type5_3_ 
    from
        costumers costumer0_

The deteleAll() on @AfterTransaction the output sql includes the delete query.

@AfterTransaction
    public void afterTransatcion(){
        // List<Costumer> costumers = costumerService.findAll();
        costumerService.deleteAll();
    }


Hibernate: 
    select
        costumer0_.id as id1_3_,
        costumer0_.cpf_cnpj as cpf_cnpj2_3_,
        costumer0_.email as email3_3_,
        costumer0_.name as name4_3_,
        costumer0_.type as type5_3_ 
    from
        costumers costumer0_
Hibernate: 
    delete 
    from
        phones 
    where
        costumer_id=?
Hibernate: 
    delete 
    from
        costumers 
    where
        id=?
Pablo Souza
  • 863
  • 2
  • 11
  • 25
  • Your test is connected to a real database, or to an in-memory database? – Adina Rolea Feb 26 '19 at 18:31
  • Connected to a real MySql database. After calling the `deleteAll()` method the data still exists on database. – Pablo Souza Feb 26 '19 at 18:58
  • That's the natural behavior of the Tests. All the changes done by the Test will be rolled back once the Test completes. If you don't want this default behaviour, you can use `@Rollback(false)` onto your tests. – The Coder Feb 26 '19 at 20:27
  • @TheCoder It doesn't work. – Pablo Souza Feb 26 '19 at 21:58
  • Try deleteAll() inside your test only. Put the `hibernate.show_sql=true`. This will make us sure, where the delete SQL is getting triggered or not. – The Coder Feb 27 '19 at 04:45
  • And btw, why you even want to deleteAll ? This would be done by rollback automatically for you. – The Coder Feb 27 '19 at 04:49
  • @TheCoder thats the point! For any reason the test is not rolling back automatically. After tests end I can see the records on database. I just send the result with `hibernate.show_sql=true` – Pablo Souza Feb 27 '19 at 09:17
  • Can you also try replacing the `@Before` with `@BeforeEach` and `@After` with `@AfterEach` and `@RunWith(SpringJUnit4ClassRunner.class)` – The Coder Feb 27 '19 at 10:05
  • 1
    Is your DB type InnoDB? This may help https://stackoverflow.com/questions/2827770/why-are-transactions-not-rolling-back-when-using-springjunit4classrunner-mysql-s – The Coder Feb 27 '19 at 10:13
  • You're right!! That´s the problem! My connection config was using a weird driver class name `driverClassName: com.mysql.cj.jdbc.Driver` instead of `com.mysql.jdbc.Driver`. After change that it works perfectlly even removing the `deleteAll()` !! I keep the `dialect: org.hibernate.dialect.MySQL5Dialect` instead of the InnoDB `org.hibernate.dialect.MySQLInnoDBDialect` and keeps working! Thanks @TheCoder – Pablo Souza Feb 27 '19 at 11:37
  • 1
    your welcome.... – The Coder Feb 27 '19 at 11:59

2 Answers2

3

In my junit, after adding repository.deleteAllInBatch() inside @BeforeEach method worked for me. Faced this issue only during execution of junit.

@BeforeEach
public void config()
{
   repository.deleteAllInBatch()
}
BALAJI RAJ
  • 125
  • 2
  • 9
0

The data will be deleted from the database when the transaction is closed. Which should happen only at the very end of your test method.

But, because you are using transactional-tests, all transactions will be auto-rollback after the tests.

By default, test transactions will be automatically rolled back after completion of the test; however, transactional commit and rollback behavior can be configured declaratively via the @Commit and @Rollback annotations

Selindek
  • 3,269
  • 1
  • 18
  • 25
  • But the records on database are never deleted even calling the `deleteAll()` – Pablo Souza Feb 26 '19 at 19:39
  • Only if you call that record from the test. The delete will be rolled back at the end of the test. Add `@Rollback(false)` to your test. – Selindek Feb 26 '19 at 19:46
  • Sorry. Not working with `@Rollback(false)`. Not working with `@Commit`. Not working with both `@Rollback(false)` and `@Commit` together! The data still on database after the `@After` test call `deleteAll()` – Pablo Souza Feb 26 '19 at 21:56
  • 1
    It works with `@AfterTransaction public void afterTransatcion(){ costumerService.deleteAll(); }` but I don´t know if it make sense considering the default roll back behavior – Pablo Souza Feb 26 '19 at 22:58