java - 当我想忽略其余参数时,如何验证是否使用正确的参数调用服务?
问题描述
我有SomeService
一个有方法的类verify(Company company, Location location)
;Location
是枚举 -Location.EUROPE
和Location.USA
. 根据我选择不同的电子邮件模板的位置,我在里面有私有方法SomeService
:
private String chooseServiceResource(Location location){
if(location.equals(Location.EUROPE))
return "resourceEU";
return "resourceUSA";
}
在someService(Company company, Location location)
我调用chooseServiceResource(location)
并选择正确的模板字符串。
public void someService(Company company, Location location) {
String name = company.getName();
String info = company.getInfo();
....
String resourcee = chooseResourceTemplate(location);
String body = templateEngine.process(resource, content);
...
//do something else and send the email
}
templateEngine
被注入@Qualifier private TemplateEngine templateEngine;
更新:
里面EmailService
我有以下方法:
public void setTemplateEngine(TemplateEngine templateEngine) {
this.templateEngine = templateEngine;
}
我通过以下方式注入它:
@Autowired
@Qualifier("textTemplateEngine")
private TemplateEngine templateEngine;
这里面EmailServiceTest
曾经是我的 setUp():
@Before
public void setup() {
ThymeleafConfig tc = new ThymeleafConfig();
templateEngine = tc.templateEngine();
MockitoAnnotations.initMocks(this);
emailService.setTemplateEngine(templateEngine);
}
是的,我知道这templateEngine
不是一个模拟,而是一个实际的对象,因此在线错误verify(templateEngine).process("templateEU", any(Content.class));
。但是当我将其更改为模拟时,我得到NullpointerException
.
更新结束
在我的测试中,我想测试当位置是欧洲时它会处理templateEU
,当位置是美国时它会处理templateEU
。
我尝试了以下方法:
@Test
public void shouldCallTemplateEngineWithEuropeTemplate(){
location = Location.EUROPE;
//throws null pointer exception
emailService.sendEmail(any(Person.class), location);
verify(templateEngine).process("templateEU", any(Content.class));
}
但它抱怨我在嘲笑Person
参数。在这个特定的测试中,我不关心Person
我发送的是哪个对象,我只关心Location
枚举。
解决方案
在对模拟依赖项安排或断言成员调用时使用参数匹配器。
在执行被测成员时,它们不会作为参数使用/传递,实际上会传递类型的默认值,在这种情况下为null。因此,当
String name = person.getName();
叫做。
相反,创建参数的实例并将其传递给被测对象。
//Arrange
location = Location.EUROPE;
Person person = new Person();
//Act
emailService.sendEmail(person, location);
//Assert
//...
或者只是模拟类并传递它以避免空引用错误
//Arrange
location = Location.EUROPE;
Person person = mock(Person.class);
//Act
emailService.sendEmail(person, location);
//Assert
//...
确保设置任何成员调用Person
,如果未配置会导致问题。
至于模板问题,您应该模拟模板,以便单元测试真正成为一个孤立的测试。
@Before
public void setup() {
templateEngine = mock(TemplateEngine.class); //Use a mock
MockitoAnnotations.initMocks(this);
emailService.setTemplateEngine(templateEngine);
}
和
verify(templateEngine).process("templateEU", any(Content.class));
行为符合预期。
推荐阅读
- python - 如何在 numpy 数组中找到元组的索引?
- java - 在 Java 中绑定 Yaml 属性时出现异常
- javascript - Vue.js 路由不起作用时的常见错误是什么?
- laravel - Laravel - 每天在 randon 选择五个用户
- c# - 如何将“06/22/2019 00:00:00”的字符串转换为格式为 2019/06/22 的有效 DateTime 类型,而不包含小时、分钟和秒的部分
- mysql - 使用从最后一个值到下一个填充值的值更新列
- scala - 在 Scala 中,特征定义名称后的大括号是什么意思?
- python - 使用 Selenium 从框架下的嵌套 HTML 代码中识别元素(确认没有 iframe)
- javascript - 如何使这段代码从项目中删除类名,并使用 getElementsByClassName 并使这个手风琴按我想要的方式工作?
- google-apps-script - 如何在 Google Script 上下文中保存 HTML 下拉列表值?