Spring 使用 mockito 的 MVC 模拟未发生在服务层

Spring MVC mocking using mockito not happening on service layer

这是我的控制器:


@RestController
public class LoanController {
    
    @Autowired 
    private LoanService loanService;
        
    @GetMapping("/loans/{id}")
    public Loan getLoan(@PathVariable Long id) {
        return loanService.getLoan(id);
    }   
    
    @PostMapping("/loans")
    public ResponseEntity <String> addLoan(@RequestBody Loan loan) {
        System.out.println(" Test 2 >> " + loanService.isLoanProcessed(loan));
        
        if(loanService.isLoanProcessed(loan)) {
            return ResponseEntity.status(HttpStatus.CREATED).build(); //return http 201 return code
        }
        return ResponseEntity.status(HttpStatus.CONFLICT).build(); // return http 409 return code
        
    }   
}

服务:

@Service
public class LoanService {
    
    @Autowired
    private LoanRepository loanRepo;

    public boolean isLoanProcessed(Loan loan) {
        // Validate the Loan
        if(isValid(loan)) {
            
            // Get the Loan Fee
            Double loanFees = getLoanFees(loan.getLoanType().trim());
            
            // Get the total Loan Interest
            Double totLoanInterest = calcLoanTotalInterest(loan.getLoanAmt(),loan.getRate(),loan.getLoanTerm());
            
            // Get the APR
            Double apr = getAPR(totLoanInterest,loanFees,loan.getLoanAmt(),loan.getLoanTerm());
            
            // Set calculate APR to Loan model
            loan.setApr(apr);
            
            // Add the loan to db
            this.addLoan(loan);
            
            return true;
            
        } else {
            // If the Loan is not valid throw custom exception
            // Still need to be implemented
            return false;
        }
}

这是测试类:

@SpringBootTest
@AutoConfigureMockMvc
public class LoanControllerIntegrationTests {
    
    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private LoanService mockLoanService;
    private AutoCloseable closeable;
    
    @InjectMocks
    LoanController loanController;
    
    private Loan loan;
    private SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
    
    
    @BeforeEach
    public void init() throws Exception {
        closeable = MockitoAnnotations.openMocks(this);
        
        mockMvc = MockMvcBuilders.standaloneSetup(loanController).build();
        
    }

   @Test
    @DisplayName("POST /loans")
    final void addLoanIdTest() throws Exception {
        loan.setApr(Double.valueOf(5.15));
        loan.setLoanStatus("A");
        
        when(mockLoanService.isLoanProcessed(loan)).thenReturn(true);
        
        System.out.println(" Test 1 >> " + mockLoanService.isLoanProcessed(loan));  // printing true
        
        mockMvc.perform(post("/loans")
                .contentType(MediaType.APPLICATION_JSON)
                .content(convertObjToJsonString(loan)))
                .andExpect(status().isOk());
          
    }  

这是我的问题: 在测试中,当我在 mockLoanService.isLoanProcessed(loan) 值上打印时模拟正确发生,这是正确的,但在控制器中,post 方法修改模拟数据没有选择,当我打印显示为 false ,使用模拟数据未对控制器 if(loanService.isLoanProcessed(loan)) 进行条件检查。请在我出错的地方提供您的意见。

在您之前的方法中,尝试添加:

MockitoAnnotations.initMocks(this);

它不起作用,因为您将 mock 绑定到在 LoanControllerIntegrationTests class 中创建的特定 Loan 对象。在控制器中创建的对象不是同一个对象。

简单示例:

要解决您的问题,请使用any()运算符:

when(mockLoanService.isLoanProcessed(any(Loan.class))).thenReturn(true);

您可以从以下导入语句中获取: import static org.mockito.ArgumentMatchers.any;