mockito 预期值:用户的Mock,hashCode:1835841364实际:空

slsn1g29  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(128)

我为我的UserService类编写了一个模拟测试,但不明白为什么create方法的测试显示为橙子。我想弄清楚这是由于拼写错误的方法还是拼写错误的测试。这是我的命令类。

  1. /**
  2. * A class that represents an order and contains the selected products and the customer.
  3. */
  4. @Entity
  5. @Table(name = "orders", schema = "public")
  6. public class Order {
  7. @Id
  8. @GeneratedValue(strategy = GenerationType.IDENTITY)
  9. private Long id;
  10. @ManyToOne
  11. //@JoinColumn
  12. private Product product;
  13. @ManyToMany
  14. private List<Product> products;
  15. @ManyToOne(fetch = FetchType.LAZY)
  16. //Multiple orders can belong to one customer. This means that a customer can place several orders.
  17. private User user;
  18. public Order() {
  19. //Default constructor
  20. }
  21. public Order(User user, Product product) {
  22. this.user = user;
  23. this.product = product;
  24. }
  25. public Long getId() {
  26. return id;
  27. }
  28. public void setId(Long id) {
  29. this.id = id;
  30. }
  31. public Product getProduct() {
  32. return product;
  33. }
  34. public void setProduct(Product product) {
  35. this.product = product;
  36. }
  37. public List<Product> getProducts() {
  38. return products;
  39. }
  40. public void setProducts(List<Product> products) {
  41. this.products = products;
  42. }
  43. public User getUser() {
  44. return user;
  45. }
  46. public void setUser(User user) {
  47. this.user = user;
  48. }
  49. }

我的OrderService类:

  1. /**
  2. * A class that implements the order process and includes functions to create orders, display the order history of a customer and confirm the order.
  3. */
  4. @Service
  5. public class OrderService {
  6. @Autowired
  7. OrderRepository or;
  8. public void save(Order order) {
  9. or.save(order);
  10. }
  11. public List<Order> listAll(){
  12. return (List<Order>) or.findAll();
  13. }
  14. public Order create(User user, Product product) {
  15. Order newOrder = new Order();
  16. newOrder.setUser(user);
  17. newOrder.setProduct(product);
  18. return or.save(newOrder);
  19. }
  20. public void delete(Long id) {
  21. Optional<Order> existingOrder= or.findById(id);
  22. if(existingOrder.isPresent()){
  23. or.deleteById(id);
  24. } else {
  25. throw new IllegalArgumentException("Order with ID " + id + " not found.");
  26. }
  27. }
  28. }

Meine Klasse订单存储库:

  1. @Repository
  2. public interface OrderRepository extends CrudRepository<Order, Long> {
  3. long countById(Long id); }

下面是显示为橙子的模拟测试:

  1. public class OrderServiceTest {
  2. @InjectMocks
  3. private OrderService orderService;
  4. @InjectMocks
  5. private ProductService productService;
  6. @Mock
  7. private OrderRepository orderRepository;
  8. @Mock
  9. private ProductRepository productRepository;
  10. @BeforeEach
  11. public void setUp() {
  12. MockitoAnnotations.openMocks(this);
  13. }
  14. @Test
  15. public void testCreateOrder() {
  16. MockitoAnnotations.openMocks(this);
  17. Product product = new Product();
  18. product.setProductName("productName_0");
  19. product.setProductSalePrice(1290.78);
  20. User mockUser = Mockito.mock(User.class); // Create a mock User object
  21. Order mockOrder = new Order();
  22. when(orderRepository.save(any(Order.class))).thenReturn(mockOrder);
  23. Order createdOrder = orderService.create(mockUser, product);
  24. assertNotNull(createdOrder);
  25. assertEquals(mockUser, createdOrder.getUser());
  26. assertEquals(product, createdOrder.getProduct());
  27. verify(orderRepository, times(1)).save(any(Order.class));
  28. }

enter image description here我已经尝试在测试中进行更改。因为在数据库中,它被正确地标记为“用户”,更具体地说是“用户ID”,所以这对我来说更令人困惑。

xwbd5t1u

xwbd5t1u1#

让我们来分解一下:

  1. Order mockOrder = new Order(); // this is not a Mockito mock
  2. when(orderRepository.save(any(Order.class))).thenReturn(mockOrder);
  3. Order createdOrder = orderService.create(mockUser, product);
  4. // at this point: createdOrder == mockOrder (same reference)

使用无参数构造函数的Order类(new Order()):

  1. public class Order {
  2. private Long id;
  3. private Product product;
  4. private List<Product> products;
  5. private User user;
  6. public Order() {
  7. // Parameterless constructor: all fields default-initialized
  8. }
  9. // ...
  10. }

然后你的Assert:

  1. assertEquals(mockUser, createdOrder.getUser());

记住:createdOrder == mockOrdermockOrder只是类的默认初始化示例,所以它的user字段仍然是null
如果你要求你的测试双精度型返回特定的值,你必须相应地设置它们。但我想知道你的测试是什么。你可能会完全搞砸你的服务实现,把错误的Order示例传递给你的仓库,等等。你的测试仍然会成功,因为唯一相关的行是return or.save(newOrder),并且该方法被存根为when(orderRepository.save(any(Order.class))).thenReturn(mockOrder),这意味着它将返回相同的mockOrder示例,对于除了null之外的任何输入。
你的测试不是测试任何有用的东西。它只是测试Mockito可以存根接口调用的返回值。
更有意义的测试可能是:

  1. @Test
  2. public void testCreateOrder() {
  3. Product product = new Product();
  4. product.setProductName("productName_0");
  5. product.setProductSalePrice(1290.78);
  6. User mockUser = Mockito.mock();
  7. orderService.create(mockUser, product);
  8. final ArgumentCaptor<Order> captor
  9. = ArgumentCaptor.forClass(Order.class);
  10. verify(orderRepository).save(captor.capture());
  11. final Order savedOrder = captor.getValue();
  12. assertEquals(mockUser, order.getUser());
  13. assertEquals(product, order.getProduct());
  14. }

它验证repository.save是否已被调用,订单中的用户和产品设置是否正确。但是如果您正在测试数据库交互,我建议您编写一个集成测试,它实际上可以持久化您的实体。

展开查看全部

相关问题