Home > Software design >  JUnit5 test case calls @Transactional function
JUnit5 test case calls @Transactional function

Time:01-30

Given a TestClass with TestMethod for an integration test (spawning MySQL Testcontainer behind the scenes)

@SpringBootTest
public class InsertAnythingIntegrationTest {

  private DoAnythingHandler handler;

  @Autowired
  private AnythingRepository anythingRepository;
  
  @BeforeEach
  void beforeEach() {
    handler = new DoAnythingHandler(anythingRepository);
  }
  @Test
  void handle_shouldAddEntry_givenValidValue() {
      handler.insertSomething(new Entity(x,y,z));
      assertThat(anythingRepository.findAll()).isEqualTo(1);
  }
}

and the Handler implementation annotated with @Transactional

@Component
public class DoAnythingHandler() {

  @Autowired
  private AnythingRepository anythingRepository;

  @Autowired
  private ApplicationEventPublisher applicationEventPublisher;

  @Transactional
  public void insertOrUpdateSomething(Entity entity) {
    var existingEntity = anythingRepository.findById(entity.getId());

    if (existingEntity != null) {
      existingEntity.valueX = entity.x;
      existingEntity.valueY = entity.Y;
      existingEntity.valueZ = entity.Z;
    } else {
      anythingRepository.save(entity);
    }
    applicationEventPublisher.publishEvent(new AnyFurtherEventUpdatingDb(entity.X, entity.Y));
  }
}

If I run this test, the transaction is never opened since it needs to be called from Bean to Bean to apply the @Transactional annotation.

How can I mock a Bean calling this method in my test case. I don't want my test case to be @Transactional since I am not able to assert anything. This handler is my UnitOfWork and I want no further abstraction layer whatever in place.

How to approach this?

CodePudding user response:

@Autowired
private DoAnythingHandler handler;

did the trick for me. I thought I tried this before, but maybe I did something wrong before.

Thanks to everyone!

  • Related