需要访问存储库的测试方法

时间:2019-05-16 07:23:48

标签: java spring junit mockito

我尝试学习写作测试。


@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 个答案:

答案 0 :(得分:1)

您需要模拟settingRepository的实例。仅仅使用@InjectMocks不会神奇地注入MailServiceImpl的依赖项,因为Mockito不知道如果不指定需要注入什么。

public class MailServiceImplTest {

  @InjectMocks
  private MailServiceImpl mailService;

  @Mock
  private SettingRepository settingRepository;

我不会解释@InjectMocks@Mock之间的区别,因为它超出了您的特定问题的范围,但是如果您想了解两者之间的区别,可以检查{{3 }}。

答案 1 :(得分:1)

对我来说,注释在阅读代码方面从未真正明确。 因此您可以像以下示例一样进行操作:

...

import static org.mockito.Mockito.mock;

public class MailServiceImplTest {

  private SettingRepository settingRepository = mock(SettingRepository.class);

  private MailServiceImpl mailService = new MailServiceImpl(settingRepository)

}

这样,读者可以更清楚地了解到您正在测试邮件服务,并且它具有新的实例,

您正在嘲笑存储库。

,您可以在构造函数中传递存储库。