【问题标题】:Spring MVC mocking using mockito not happening on service layer使用 mockito 的 Spring MVC 模拟未在服务层发生
【发布时间】:2021-07-12 16:41:55
【问题描述】:

这是我的控制器:


@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))没有使用模拟数据发生。请在我犯错误的地方提供您的意见。

【问题讨论】:

  • 是什么让你认为它不起作用,因为断言失败了?您正在返回在控制器中创建的 HTTP 状态,但在测试中验证 HTTP 状态是否正常。
  • 我想要控制器中的模拟服务loanService.isLoanProcessed(loan);控制器需要评估为真,以便控制器应该执行返回 ResponseEntity.status(HttpStatus.CREATED).build();并返回 201。如果您需要更多信息,请告诉我。

标签: java spring-boot spring-mvc mockito junit5


【解决方案1】:

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

简单示例:

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

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

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

【讨论】:

  • 谢谢,它解决了我的问题。然后我的下一个问题是如何获取控制器生成的 Loan 对象。
  • 我假设您想检查控制器响应。要访问响应 json,请使用 jsonPath,例如:.andExpect(jsonPath("$.loanValue").value(123.456f))
【解决方案2】:

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

MockitoAnnotations.initMocks(this);

【讨论】:

  • init() 方法添加 closeable = MockitoAnnotations.openMocks(this);认为这是要初始化模拟。
猜你喜欢
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
  • 2016-08-18
  • 1970-01-01
  • 2018-01-29
  • 2020-06-09
  • 1970-01-01
相关资源
最近更新 更多