java - 如何断言在 void 方法中创建的值?
问题描述
我有课
public class CloneUserService {
private final UserRepository userRepository;
private final PersonRepository personRepository;
private final OrderRepository orderRepository;
public CloneUserService(UserRepository userRepository, PersonRepository personRepository, OrderRepository orderRepository) {
this.userRepository = userRepository;
this.personRepository = personRepository;
this.orderRepository = orderRepository;
}
public void createFromTemplate(String templateUserId) {
User templateUser = userRepository.getUserById(templateUserId);
Person templatePerson = personRepository.getPersonByUserId(templateUserId);
List<Order> templateOrders = orderRepository.getOrdersByUserId(templateUserId);
User newUser = cloneUserFromTemplate(templateUser);
newUser.setId("newId");
userRepository.save(newUser);
Person newPerson = clonePersonFromTemplate(templatePerson);
newPerson.setUser(newUser);
newPerson.setId("newId");
personRepository.save(newPerson);
for (Order templateOrder : templateOrders) {
Order newOrder = cloneOrderFromTemplate(templateOrder);
newOrder.setId("newId");
newOrder.setUSer(newUser);
orderRepository.save(newOrder);
}
}
private Order cloneOrderFromTemplate(Order templateOrder) {
//logic
return null;
}
private Person clonePersonFromTemplate(Person templatePerson) {
//logic
return null;
}
private User cloneUserFromTemplate(User templateUser) {
//logic
return null;
}
}
我需要测试这个方法createFromTemplate
。
我创建了这个测试。我为每个存储库创建 stab,并将保存的对象存储到这个存根中。我添加了额外的方法来获取这个对象的断言。有用。但我有两个问题:
- 我的模板对象是可变的。这不是一个大问题,但这是一个事实。
- 如果我向存储库接口添加新方法,我必须在存根中实现它。
Mu 问题 - 如何从我的示例中测试像论文这样的克隆对象?
我不使用 spring 和 H2DB 或其他内存数据库。我有一个 MongoDB 数据库。如果我使用 mockito,我将不明白如何在 void 方法中断言新对象。
class CloneUserServiceTest {
private CloneUserService cloneUserService;
private UserRepositoryStub userRepository;
private PersonRepositoryStub personRepository;
private OrderRepositoryStub orderRepository;
@Before
public void setUp() {
User templateUser = new User();
Person templatePerson = new Person();
List<Order> templateOrders = Collections.singletonList(new Order());
userRepository = new UserRepositoryStub(templateUser);
personRepository = new PersonRepositoryStub(templatePerson);
orderRepository = new OrderRepositoryStub(templateOrders);
cloneUserService = new CloneUserService(userRepository, personRepository, orderRepository);
}
@Test
void createFromTemplate() {
cloneUserService.createFromTemplate("templateUserId");
User newUser = userRepository.getNewUser();
// assert newUser
Person newPerson = personRepository.getNewPerson();
// assert newPerson
Order newOrder = orderRepository.getNewOrder();
// assert newOrder
}
private static class UserRepositoryStub implements UserRepository {
private User templateUser;
private User newUser;
public UserRepositoryStub(User templateUser) {
this.templateUser = templateUser;
}
public User getUserById(String templateUserId) {
return templateUser;
}
public void save(User newUser) {
this.newUser = newUser;
}
public User getNewUser() {
return newUser;
}
}
private static class PersonRepositoryStub implements PersonRepository {
private Person templatePerson;
private Person newPerson;
public PersonRepositoryStub(Person templatePerson) {
this.templatePerson = templatePerson;
}
public Person getPersonByUserId(String templateUserId) {
return templatePerson;
}
public void save(Person newPerson) {
this.newPerson = newPerson;
}
public Person getNewPerson() {
return newPerson;
}
}
private static class OrderRepositoryStub implements OrderRepository {
private List<Order> templateOrders;
private Order newOrder;
public OrderRepositoryStub(List<Order> templateOrders) {
this.templateOrders = templateOrders;
}
public List<Order> getOrdersByUserId(String templateUserId) {
return templateOrders;
}
public void save(Order newOrder) {
this.newOrder = newOrder;
}
public Order getNewOrder() {
return newOrder;
}
}
}
解决方案
在您的场景中,我会考虑使用像 Mockito 这样的模拟框架。
一些主要优点:
- 向存储库接口添加新方法不需要在存根中实现它
- 支持精确次数和至少一次验证
- 允许按顺序进行灵活验证(例如:按您想要的顺序验证,而不是每次交互)
- 非常好的和简单的注解语法——@Mock、@InjectMocks、@Spy
这是一个示例-也许您会感兴趣:
// arrange
Warehouse mock = Mockito.mock(Warehouse.class);
//act
Order order = new Order(TALISKER, 50);
order.fill(warehouse); // fill will call remove() implicitly
// assert
Mockito.verify(warehouse).remove(TALISKER, 50); // verify that remove() method was actually called
推荐阅读
- r - ggplot 多个数字 gridExtra
- .net - .net Standard 2.0 项目的 GalaSoft.MvvmLight 包参考错误
- ruby - Ruby:使用出现限制(?)对哈希进行分组
- microsoft-graph-api - 用于创建订阅的 Microsoft 图形订阅 API 失败并显示状态代码:BadRequest
- reactjs - 反应无法使用地图访问道具
- java - 如何将文本从一个活动传递到另一个活动(android studio)
- c - 使用 while 循环时变量连续等于 nan
- c - 在 ext4 中如何进行文件名查找?
- javascript - 功能策略:跳过不支持的功能名称“画中画”/“自动播放”/“加密媒体”
- mysql - 订购时查询缓慢