簡體   English   中英

java.lang.NullPointerException:無法調用“com.proj.my.repository.OrderRepository.save(Object)”,因為“this.orderRepository”是 null

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

我想測試我的 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)

怎么會是null?? 我設法對我的產品和我的用戶進行了單元測試,但我無法按照我的訂單進行。 我的訂單.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;
    }
}

我的訂單服務.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);
    }}

我的訂單Repository.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);
    }

    
}

我已經失去了想法,因為我在 inte.net 中查找了它,但我找不到任何相似的東西。 也許我只是沒有給予正確的關注。

在您的OrderService class 中,您正在創建私有OrderRepository存儲庫 object,但是 object 是 null。

您可以通過以下兩種方式解決此問題。

  • 您可以自動裝配您的存儲庫 object

    @Autowired

    private OrderRepository orderRepository;

  • 或者你可以讓你的存儲庫 object Final

    private final 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添加到您的服務class。它應該是這樣的。 這些更改后運行您的應用程序

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

測試設置錯誤地使用了 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);
        //use a new, clean orderRepository mock for each test
        orderRepository = mock(OrderRepository.class);
        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);
    }
  ..

    @Test 
    void testSaveOrder(){
        when(orderRepository.save(order)).thenReturn(order);  
        assertThat(orderService.saveOrder(order)).isEqualTo(order);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM