Метод тестирования, который требует доступа к хранилищу - PullRequest
0 голосов
/ 16 мая 2019

Я пытаюсь научиться писать тесты.


@Service
public class MailServiceImpl {
  @Autowired
  private SettingRepository settingRepository;

  public String buildTemplate(Template template, Map<String, String> templateParameters) {

    final String templateHeader = settingRepository.findByKey("test1").getValue();
    final String templateFooter = settingRepository.findByKey("test2").getValue();

    String content = replaceParameters(template.getContent(), templateParameters);

    StringBuilder builder = new StringBuilder();
    builder.append(templateHeader);
    builder.append(content);
    builder.append(templateFooter);

    return builder.toString();
  }

  private String replaceParameters(String content, Map<String, String> templateParameters) {
    for (Entry<String, String> parameter : templateParameters.entrySet()) {
      content = content.replace(
          String.format("{{ %s }}", parameter.getKey()),
          parameter.getValue()
      );
    }
    return content;
  }
}

public class MailServiceImplTest {

  @InjectMocks
  MailServiceImpl mailService;

  @Before
  public void setup() {
    initMocks(this);
  }

  @Test
  public void buildTemplate() {

    Template template = new Template();
    template.setContent("lorem ipsum");

    String content = mailService.buildTemplate(template, new HashMap<>());

    // assertion
  }
}

Моя проблема в этой части:

final String templateHeader = settingRepository.findByKey("test1").getValue();

Я получаю исключение "NullPointerException", если возможно протестировать этот метод без каких-либо изменений кода?

База данных - MongoDB, поэтому мне нужно создать "виртуальные" некоторые документы с ключами "test1", "test2"?


@Repository
public interface SettingRepository extends PagingAndSortingRepository<Setting, String> {

  Setting findByKey(String id);
}

Спасибо за помощь


Решение:

  @Test
  public void buildTemplate() {
Mockito.when(settingRepository.findByKey("test1")).thenReturn(new Setting());
    Mockito.when(settingRepository.findByKey("test2")).thenReturn(new Setting());
}

Ответы [ 2 ]

1 голос
/ 16 мая 2019

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

...

import static org.mockito.Mockito.mock;

public class MailServiceImplTest {

  private SettingRepository settingRepository = mock(SettingRepository.class);

  private MailServiceImpl mailService = new MailServiceImpl(settingRepository)

}

таким образом, читателю станет понятнее, что вы тестируете почтовый сервис, и у него есть новый экземпляр,

, и вывысмеивать хранилище.

и вы можете передать хранилище в конструкторе.

1 голос
/ 16 мая 2019

Вам нужно смоделировать экземпляр settingRepository.Простое использование @InjectMocks не приведет к магическому внедрению зависимостей MailServiceImpl, поскольку Mockito не имеет ни малейшего представления о том, что нужно вводить, если вы не укажете его.

public class MailServiceImplTest {

  @InjectMocks
  private MailServiceImpl mailService;

  @Mock
  private SettingRepository settingRepository;

Я не буду объяснять разницумежду @InjectMocks и @Mock, поскольку это выходит за рамки вашего конкретного вопроса, но если вы хотите понять разницу между ними, вы можете проверить этот вопрос .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...