Java 我可以在这个场景中编写任何有意义的单元测试吗?
我有这个实体-Java 我可以在这个场景中编写任何有意义的单元测试吗?,java,unit-testing,junit,testability,Java,Unit Testing,Junit,Testability,我有这个实体- public class MerchantConfig { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private Long merchantId; private String configKey; private String configValue; .. } 目前,它在商户级别存储配置(密钥和值) 我们现在也需要在用户
public class MerchantConfig {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Long merchantId;
private String configKey;
private String configValue;
..
}
目前,它在商户级别存储配置(密钥和值)
我们现在也需要在用户级别存储配置(用户到商家一对多映射)
我们将这两列添加到实体中-
private Long entityId;
private String entityType;
entityId现在将存储merchantId/UserId,entityType将用字符串值“merchantId”或“user\u id”指示相同的值
下面是一个现有的服务层方法-
public MerchantConfig enableSync(boolean isActive, Long merchantId,boolean isSync){
MerchantConfig merchantConfig= merchantConfigRespository.findByMerchantIdAndConfigKey(merchantId,Constants.MerchantConfigKeys.SYNC_ENABLED.key);
if(merchantConfig==null){
merchantConfig = new MerchantConfig();
merchantConfig.setMerchantId(merchantId);
merchantConfig.setConfigKey(Constants.MerchantConfigKeys.SYNC_ENABLED.key);
}
if(isSync)
merchantConfig.setConfigValue("1");
else
merchantConfig.setConfigValue("0");
merchantConfig.setIsActive(isActive);
return merchantConfigRespository.save(merchantConfig);
}
这是它上面的控制器-
@PostMapping("/admin/enableSync")
public ResponseEntity<Object> enableSync(HttpServletRequest request, HttpServletResponse response,
@RequestParam("merchantId") Long merchantId,
@RequestParam("isValid") boolean isValid,
@RequestParam("isSync") boolean isSync) {
if (isValid && isSync)
LOGGER.info("enabling sync for merchant {}", merchantId);
else
LOGGER.info("disabling sync for merchant {}", merchantId);
MerchantConfig merchantConfig = merchantConfigService.enableSync(isValid, merchantId, isSync);
if(merchantConfig!=null)
return new ResponseEntity<>(new ResponseDTO(Constants.API_RESPONSE_SUCCESS, merchantConfig, "success"),
HttpStatus.OK);
return new ResponseEntity<>(new ResponseDTO(Constants.API_RESPONSE_FAILURE, "unable to enable sync"),
HttpStatus.OK);
}
我在服务层放了什么有用的单元测试用例
如果我要模拟存储库层响应,并验证服务方法返回的MerchantConfig实体与模拟的响应相同,这会不会是一种过分的做法
相反,我觉得测试db值更有用,方法是向db中输入一些已知的条目。例如,在这种情况下,当数据库中已经有一些商户级配置,并且要输入用户级配置时,用户级条目应该覆盖,因为配置程序正在尝试取消设置所有商户级配置
如果给定db中的商户级配置,当调用save config API端点以保存用户级配置时,测试商户级配置是否被标记为不活动是很有用的
顺便问一下,这些测试叫什么?请给出一些解决方案,因为我在这场辩论中挣扎了很长时间。每次我坐下来写传统的单元测试用例时,我花费了太多的时间,但仍然有一些东西出现了问题,单元测试无法涵盖这些问题。请提供一些全面的指南来编写这样的测试。首先,感谢您的提问! 这是一个好问题,让我思考。现在关于答案 如果有任何科学证明是编写测试的唯一正确方法,我不知道。作为一名专业人士,你必须打个电话。如果我是你,我会考虑这些事情:
- 为几行更改编写单元测试看起来确实有些过分。很容易想象一个人如何以30行单元测试结束,并通过模拟来测试几行更改。让它成为选项1
- 另一方面,使用DB编写集成测试(为了测试起见,可能在内存中)现在看起来可能是一个简单的解决方案。让它成为选项2
- 速度。单元测试的运行和调试速度总是更快(即使它们的编写时间更长)
- 粒度。通过单元测试,我几乎总是知道问题在哪里
enableSync
对许多事情都有作用(即创建/查找对象并切换同步标志)
如果将下面的代码提取到一个单独的方法中(例如,buildmerchantConfig
):
MerchantConfig-MerchantConfig=
if(merchantConfig==null){
merchantConfig=新merchantConfig();
merchantConfig.setEntityId(merchantId);
merchantConfig.setEntityType(枚举MerchantConfigType.MERCHANT_ID.v);
merchantConfig.setConfigKey(常量.MerchantConfigKeys.SYNC_ENABLED.key);
}
这应该很容易进行单元测试,并且不需要DB交互或模拟。首先,感谢您的提问! 这是一个好问题,让我思考。现在关于答案 如果有任何科学证明是编写测试的唯一正确方法,我不知道。作为一名专业人士,你必须打个电话。如果我是你,我会考虑这些事情:
- 为几行更改编写单元测试看起来确实有些过分。很容易想象一个人如何以30行单元测试结束,并通过模拟来测试几行更改。让它成为选项1
- 另一方面,使用DB编写集成测试(为了测试起见,可能在内存中)现在看起来可能是一个简单的解决方案。让它成为选项2
- 速度。单元测试的运行和调试速度总是更快(即使它们的编写时间更长)
- 粒度。通过单元测试,我几乎总是知道问题在哪里
enableSync
对许多事情都有作用(即创建/查找对象并切换同步标志)
如果将下面的代码提取到一个单独的方法中(例如,buildmerchantConfig
):
MerchantConfig-MerchantConfig=
if(merchantConfig==null){
merchantConfig=新merchantConfig();
merchantConfig.setEntityId(merchantId);
merchantConfig.setEntityType(枚举MerchantConfigType.MERCHANT_ID.v);
商品配置
public MerchantConfig enableSync(boolean isActive, Long merchantId,boolean isSync){
MerchantConfig merchantConfig= merchantConfigRespository.findByEntityIdAndEntityTypeAndConfigKey(merchantId,Enum.MerchantConfigType.MERCHANT_ID.v,Constants.MerchantConfigKeys.SYNC_ENABLED.key);
if(merchantConfig==null){
merchantConfig = new MerchantConfig();
merchantConfig.setEntityId(merchantId);
merchantConfig.setEntityType(Enum.MerchantConfigType.MERCHANT_ID.v);
merchantConfig.setConfigKey(Constants.MerchantConfigKeys.SYNC_ENABLED.key);
}
if(isSync)
merchantConfig.setConfigValue("1");
else
merchantConfig.setConfigValue("0");
merchantConfig.setIsActive(isActive);
return merchantConfigRespository.save(merchantConfig);
}