mysql - java.lang.NullPointerException : Cannot invoke "com.proj.my.repository.OrderRepository.save(Object)" because "this.orderRepository" is null

标签 mysql spring-boot unit-testing jpa crud-repository

我想测试我的orderService,每个订单有x个cartItems,每个cartItem是一个产品。 我设法编写了一些代码,并认为我做对了,但遇到了问题:

java.lang.NullPointerException: Cannot invoke "com.proj.my.repository.OrderRepository.save(Object)" because "this.orderRepository" is null
 at com.proj.my.service.impl.OrderServiceTest.testSaveOrder(OrderServiceTest.java:68)
 at java.base/java.util.ArrayList.forEach(Unknown Source)
 at java.base/java.util.ArrayList.forEach(Unknown Source)

怎么可以为空呢? 我设法对我的产品和我的用户进行单元测试,但我无法对我的订单进行单元测试。 我的订单.java

package com.proj.my.model;
import java.time.LocalDate;
import java.util.List;

import org.hibernate.annotations.CreationTimestamp;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.ToString;

@ToString
@Entity
@Table(name = "myorder")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt"}, 
    allowGetters = true)  
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    
    @OneToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "userId")
    private User user;


    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, targetEntity = ShoppingCart.class)
    @JoinColumn(name = "order_id")
    private List<ShoppingCart> cartItems;
    @CreationTimestamp
    @Column(updatable = false, name = "createdAt")
    private LocalDate createdAt;

    public LocalDate getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(LocalDate createdAt) {
        this.createdAt = createdAt;
    }

    public Order() {
    }

    public Order(User user, LocalDate createdAt, List<ShoppingCart> cartItems) {
        this.user = user;
        this.cartItems = cartItems;
        this.createdAt = createdAt;
    }

    public Order(int i, LocalDate now, List<ShoppingCart> cartItems2) {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public User getUser() {
        return user;
    }

    public void setCustomer(User user) {
        this.user = user;
    }

    public List<ShoppingCart> getCartItems() {
        return cartItems;
    }

    public void setCartItems(List<ShoppingCart> cartItems) {
        this.cartItems = cartItems;
    }
}

我的orderService.java

package com.proj.my.service;

import com.proj.my.model.Order;
import com.proj.my.model.CloudProduct;
import com.proj.my.model.ShoppingCart;
import com.proj.my.repository.OrderRepository;
import com.proj.my.repository.CloudProductRepository;

import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

@Service
public class OrderService {

    private OrderRepository orderRepository;
    private CloudProductRepository cloudProductRepository;

    public OrderService(OrderRepository orderRepository, CloudProductRepository cloudProductRepository) {
        this.orderRepository = orderRepository;
        this.cloudProductRepository = cloudProductRepository;
    }

    public Order getOrderDetail(int orderId) {
        Optional<Order> order = this.orderRepository.findById(orderId);
        return order.isPresent() ? order.get() : null;
    }
    
   public List<Order> getAllOrderDetail(LocalDate yesterday, LocalDate today) {
        today = LocalDate.now();
        yesterday = today.minusDays(1);
        return orderRepository.findAllByCreatedAtBetween(yesterday, today);
    }

    public float getCartAmount(List<ShoppingCart> shoppingCartList) {

        float totalCartAmount = 0f;
        float singleCartAmount = 0f;

        for (ShoppingCart cart : shoppingCartList) {

            String cloudProductName = cart.getProductName();
            Optional<CloudProduct> product = cloudProductRepository.findByProductName(cloudProductName);
            if (product.isPresent()) {
                CloudProduct cloudproduct = product.get();
                singleCartAmount = cart.getQuantity() * cloudproduct.getpriceInEuros();
                
                totalCartAmount = totalCartAmount + singleCartAmount;
                cart.setProductId(cloudproduct.getProductId());
                cart.setAmount(singleCartAmount);
                cloudProductRepository.save(cloudproduct);
            }
        }
        return totalCartAmount;
    }

    public Order saveOrder(Order order) {
        return orderRepository.save(order);
    }
}

我的orderController.java

package com.proj.my.controller;

import java.time.LocalDate;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.proj.my.dto.OrderDTO;
import com.proj.my.dto.ResponseOrderDTO;
import com.proj.my.model.Order;
import com.proj.my.model.User;
import com.proj.my.service.CloudProductService;
import com.proj.my.service.OrderService;
import com.proj.my.service.UserService;

@RestController
@RequestMapping("/api")
public class OrderController {

    private OrderService orderService;
    private CloudProductService cloudProductService;
    private UserService userService;


    public OrderController(OrderService orderService, CloudProductService cloudProductService, UserService userService) {
        this.orderService = orderService;
        this.cloudProductService = cloudProductService;
        this.userService = userService;
    }

    @GetMapping(value = "/getOrder/{orderId}")
    public ResponseEntity<Order> getOrderDetails(@PathVariable int orderId) {

        Order order = orderService.getOrderDetail(orderId);
        return ResponseEntity.ok(order);
    }

    @GetMapping(value = "/getOrder")
    public List<Order> getAllOrderDetails(LocalDate yesterday, LocalDate today) {
        return orderService.getAllOrderDetail(yesterday, today);
    }

    @PostMapping("/placeOrder")
    public ResponseEntity<ResponseOrderDTO> placeOrder(@RequestBody OrderDTO orderDTO) {

        ResponseOrderDTO responseOrderDTO = new ResponseOrderDTO();

        float amount = orderService.getCartAmount(orderDTO.getCartItems());

        User user = new User(orderDTO.getuserName(), orderDTO.getuserEmail());
        
        Integer userIdFromDb = userService.isUserPresent(user);

        if (userIdFromDb != null) {
            user.setUserId(userIdFromDb);
        }else{
            user = userService.createUser(user);
        }

        LocalDate createdAt = LocalDate.now(); 

        Order order = new Order(user, createdAt, orderDTO.getCartItems());

        order = orderService.saveOrder(order);

        responseOrderDTO.setAmount(amount);

        responseOrderDTO.setDate(com.proj.my.util.DateUtil.getCurrentDateTime());
        
        responseOrderDTO.setOrderId(order.getId());


        return ResponseEntity.ok(responseOrderDTO);
    }}

我的orderRepository.java

package com.proj.my.repository;

import com.proj.my.model.Order;

import java.sql.Date;
import java.time.LocalDate;
import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface OrderRepository extends JpaRepository<Order,Integer> {

    List<Order> findAllByCreatedAtBetween(LocalDate d1, LocalDate d2);
}

最后是我的 orderServiceTest.java

package com.proj.my.service.impl;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import com.proj.my.model.CloudProduct;
import com.proj.my.model.Order;
import com.proj.my.model.ShoppingCart;
import com.proj.my.repository.CloudProductRepository;
import com.proj.my.repository.OrderRepository;
import com.proj.my.repository.ShoppingCartRepository;
import com.proj.my.service.OrderService;
import com.proj.my.service.CloudProductService;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

public class OrderServiceTest {
    @Mock
    private CloudProductRepository cloudProductRepository;
    private CloudProductService cloudProductService;
    private OrderRepository orderRepository;    
    private OrderService orderService;
    Order order;
    CloudProduct cloudProduct;
    ShoppingCart shoppingCart;
    private ShoppingCartRepository shoppingCartRepository;
    AutoCloseable autoCloseable;

   
    @BeforeEach
    void setUp() {
        autoCloseable = MockitoAnnotations.openMocks(this);
        cloudProductService = new CloudProductServiceImpl(cloudProductRepository);
        cloudProduct = new CloudProduct(1, "Maria", (float) 232);
        orderService = new OrderService(orderRepository, cloudProductRepository);
        shoppingCart = new ShoppingCart("Maria", 2);
        List<ShoppingCart> cartItems = Arrays.asList(shoppingCart);
        order = new Order(1, LocalDate.now(), cartItems);
    }

    @AfterEach
    void tearDown() throws Exception {
        autoCloseable.close();
    }

    @Test 
    void testSaveOrder(){
        mock(CloudProduct.class);
        mock(CloudProductRepository.class);
        mock(Order.class);
        mock(OrderRepository.class);
        mock(ShoppingCart.class);
        mock(ShoppingCartRepository.class);

        when(orderRepository.save(order)).thenReturn(order);  <----------Error here
        assertThat(orderService.saveOrder(order)).isEqualTo(order);
    }

    
}

我已经没有想法了,因为我在互联网上查找了它,但找不到任何相似的东西。也许我只是没有给予适当的关注。

最佳答案

在您的 OrderService 类中,您将创建一个私有(private) OrderRepository 存储库对象,但该对象为 null。

您可以通过以下两种方式解决此问题。

  • 您可以 Autowiring 存储库对象

    @Autowired

    私有(private) OrderRepository orderRepository;

  • 或者您可以将存储库对象设为Final

    私有(private)最终 OrderRepository orderRepository;

更新

将 Lombok 依赖项添加到您的 Maven pom.xml 文件

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.24</version>
    <scope>provided</scope>
</dependency>

然后将@RequiredArgsConstructor@AllArgsConstructor添加到您的服务类中。它应该看起来像这样。在这些更改之后运行您的应用程序

@AllArgsConstructor
@RequiredArgsConstructor
@Service
public class OrderService {
private final OrderRepository orderRepository;
}

关于mysql - java.lang.NullPointerException : Cannot invoke "com.proj.my.repository.OrderRepository.save(Object)" because "this.orderRepository" is null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75008683/

相关文章:

php - Laravel 有很多通过 2 个表

java - 无法启动 Spring Boot 应用程序

python - 如何模拟List类型的全局变量?

Python导入机制和模块模拟

java - 如果方法在使用 Powermock 进行单元测试期间调用,如何有效验证方法

mysql - 将整数转换为小时mysql

c# - 没有数据发送到 MySQL 数据库

mysql查询;获取具有所有给定用户的所有线程

java - Spring 模块和 Spring 启动器模块之间的区别

java - Spring Boot 如何知道 Heroku 的 DATABASE_URL 配置变量?