17 Aralık 2019 Salı

SpringBoot Test @MockBean Anotasyonu

Giriş
Şu satırı dahil ederiz.
import org.springframework.boot.test.mock.mockito.MockitoBean;
Mock bir Spring bean yaratmaya yarar. Bu anotasyon @ContextConfiguration, @SpringBootTest gibi anotasyonlarla kullanılabilir. Açıklaması şöyle.
Annotation that can be used to add mocks to a Spring ApplicationContext. Can be used as a class level annotation or on fields in either @Configuraton classes, or test classes that are @RunWith SpringRunner.
Mocks can be registered by type or by bean name. Any existing single bean of the same type defined in the context will be replaced by the mock, if no existing bean is defined a new one will be added.
When @MockBean is used on a field, as well as being registered in the application context, the mock will also be injected into the field.
Not
Bu anotasyon ApplicationContext'in tekrar yüklenmesine sebep olabilir. Açıklaması şöyle. Tekrar yükleme işi testlerin süresini çok uzatabilir. Bununla ilgili bir yazı burada.
The Spring test framework will cache an ApplicationContext whenever possible between test runs. In order to be cached, the context must have an exactly equivalent configuration. Whenever you use @MockBean, you are by definition changing the context configuration.
Tekrar Yüklenmemesi İçin
Açıklama şöyle. Yani bir ata sınıf tanımlanır ve içinde @MockBean kullanılır
The solution is to have the same configuration for all the tests. That means that individual tests are not allowed to define their own @MockBean / @SpyBean. These should all be defined in a parent class.

Also notice that the @SpringBootTest annotation was moved on the parent class so we don’t have to add it to each test. The Spring test framework will cache an ApplicationContext whenever possible between test runs.
Kullanım
Mock Spring bean yarattıktan sonra Mockito kullanarak davranışı eklemek gerekir. Şöyle yaparız
Mockito.when(userRepository.findByUserName(Mockito.any())).thenReturn(new AppUser());
Örnek - @SpringBootTest
Şöyle yaparız
@SpringBootTest
class MockBeanTest {

  @MockBean
  private UserRepository userRepository;

  @Autowired
  private RegisterUseCase registerUseCase;

  @Test
  void testRegister(){
    // given
    User user = new User("Zaphod", "zaphod@galaxy.net");
    boolean sendWelcomeMail = true;
    given(userRepository.save(any(UserEntity.class))).willReturn(userEntity(1L));

    // when
    Long userId = registerUseCase.registerUser(user, sendWelcomeMail);

    // then
    assertThat(userId).isEqualTo(1L);
  }
  
}
Örnek
Şöyle yaparızz
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@WebMvcTest(UserVehicleController.class)
class MyHtmlUnitTests {

  @Autowired
  private WebClient webClient;

  @MockBean
  private UserVehicleService userVehicleService;

  @Test
  void testExample() throws Exception {
    given(this.userVehicleService.getVehicleDetails("sboot"))
      .willReturn(new VehicleDetails("Honda", "Civic"));
    HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
    assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
  }
}

Hiç yorum yok:

Yorum Gönder