Весенний загрузочный юнит-тест о лучших практиках и курсах написания тестов - PullRequest
0 голосов
/ 06 июля 2018

Я хочу начать писать модульный тест в моем проекте. Я пытался сделать это много раз. И он всегда уходил, потому что не мог понять смысл. потому что я не могу найти и сформировать знания в одно целое. Я прочитал много статей, видел много примеров, и все они разные. В результате я понимаю, почему мне нужно писать тесты, я понимаю, как их писать, но я не понимаю, как правильно. И я не понимаю, как их написать, чтобы они были полезны. У меня есть несколько вопросов:

Например, у меня есть услуга:

@Service
public class HumanServiceImpl implements HumanService {

  private final HumanRepository humanRepository;

  @Autowired
  public HumanServiceImpl(HumanRepository humanRepository) {
    this.humanRepository = humanRepository;
  }

  @Override
  public Human getOneHumanById(Long id) {
    return humanRepository.getOne(id);
  }

  @Override
  public Human getOneHumanByName(String firstName) {
    return humanRepository.findOneByFirstName(firstName);
  }

  @Override
  public Human getOneHumanRandom() {
    Human human = new Human();
    human.setId(Long.parseLong(String.valueOf(new Random(100))));
    human.setFirstName("firstName"+ System.currentTimeMillis());
    human.setLastName("LastName"+ System.currentTimeMillis());
    human.setAge(12);//any logic for create Human
    return human;
  }
}

И я попытался написать Unit test для этой службы:

@RunWith(SpringRunner.class)
public class HumanServiceImplTest {

  @MockBean(name="mokHumanRepository")
  private HumanRepository humanRepository;

  @MockBean(name = "mockHumanService")
  private HumanService humanService;

  @Before
  public void setup() {
    Human human = new Human();
    human.setId(1L);
    human.setFirstName("Bill");
    human.setLastName("Gates");
    human.setAge(50);

    when(humanRepository.getOne(1L)).thenReturn(human);
    when(humanRepository.findOneByFirstName("Bill")).thenReturn(human);
  }

  @Test
  public void getOneHumanById() {
    Human found = humanService.getOneHumanById(1L);
    assertThat(found.getFirstName()).isEqualTo("Bill");
  }

  @Test
  public void getOneHumanByName() {
    Human found = humanService.getOneHumanByName("Bill");
    assertThat(found.getFirstName()).isEqualTo("Bill");
  }

  @Test
  public void getOneHumanRandom() {
    //???
  }
}

У меня есть вопросы:

1. Где я должен заполнить объекты? Я видел разные реализации

в @Before, как в моем примере, в @Test, смешайте реализации - когда Человек создает в @Before и выражение

when(humanRepository.getOne(1L)).thenReturn(human); 

в @Test метод

  private Human human;

  @Before
  public void setup() {
    human = new Human();
    ...
  }

  @Test
  public void getOneHumanById() {
    when(humanRepository.getOne(1L)).thenReturn(human);
    Human found = humanService.getOneHumanById(1L);
    assertThat(found.getFirstName()).isEqualTo("Bill");
  }

2. Как я могу проверить метод getOneHumanRandom()?

Служба не использует хранилище при вызове этого метода. Я могу заставить этот метод издеваться, но что он даст?

when(humanService.getOneHumanRandom()).thenReturn(human);
...
@Test
  public void getOneHumanRandom() {
    Human found = humanService.getOneHumanRandom();
    assertThat(found.getFirstName()).isEqualTo("Bill");
  }

Я просто копирую логику из сервиса в тестовом классе. Какой смысл такого тестирования и нужен ли он?

1 Ответ

0 голосов
/ 06 июля 2018

1. Где я должен заполнить объекты? Я видел разные реализации

Я бы использовал @Before для любой общей настройки между всеми / большинством тестов. Любая настройка, которая является определенной для определенного теста, должна быть включена в этот метод теста. Если между некоторыми, но не всеми вашими тестами есть общие настройки, вы можете написать частные методы настройки.

Не забудьте сохранить свои тесты / код СУХИМ (не повторяйтесь!). У тестов есть фактор обслуживания и совместное использование общего кода, что поможет облегчить некоторые головные боли в будущем.

2. Как я могу проверить метод getOneHumanRandom ()?

Вы должны создать метод Human toString (). Этот метод должен объединить все свойства вашего объекта Human. Вы можете дважды вызвать getOneHumanRandom () и утверждать, что они не равны.

@Test
public void getOneHumanRandomTest()
{
    // SETUP / TEST
    Human one = service.getOneHumanRandom();
    Human two = service.getOneHumanRandom();
    // VERIFY / ASSERT
    assertNotEquals("these two objects should not be equal", one.toString(), two.toString())
}

Надеюсь, это поможет!

...