【发布时间】:2020-05-11 09:02:32
【问题描述】:
我正在为一个应用程序编写单元测试,该应用程序将具有特定货币的金额转换为欧元。我在数据库中有一些帐户:iban、货币和余额。
为了获取所有货币及其以欧元为单位的价值,需要调用 API 以获取汇率。转换方法接收账户的 iban 并从账户中返回欧元的金额。 该应用程序运行良好,但单元测试存在一些问题。
我正在尝试为找不到帐户的情况编写单元测试 - 所以当 AccountController 类中的方法 - getAccountByIban 返回 404 时。我编写了测试并添加了一个随机字符串作为 IBAN - 但是而不是 404,我得到 200 作为响应代码并且测试失败。如果我使用测试中的随机 IBAN 调用方法 getAccountByIban,我会得到正确的响应代码 - 404。
这是我的代码:
帐户控制器:
@RestController
public class AccountController {
@Autowired
RequestBuilder requestBuilder;
@Autowired
AccountService accountService;
@ApiOperation(value = "Get account with given iban ", response = AccountEntity.class)
@RequestMapping(value = "/account/{iban}", method = RequestMethod.GET )
public AccountDTO getAccountByIban(@PathVariable("iban") String iban ) throws AccountNotFoundException {
return Optional
.ofNullable(accountService.getAccountByIban(iban))
.orElseThrow(() -> new AccountNotFoundException("Requested account was not found! [ iban = " + iban + "]"));
}
@ApiOperation(value = "Get account with amount converted ", response = AccountEntity.class)
@RequestMapping(value = "/account/exchange/{iban}", method = RequestMethod.GET )
public AccountDTO getAmountConvertedByIban(@PathVariable("iban") String iban) {
AccountDTO accountDTO = accountService.getAccountByIban(iban);
Double currentBalance = accountDTO.getBalance();
String currentCurrency = accountDTO.getCurrency();
Double actualBalance = accountService.getCurrencyValue(currentCurrency) * currentBalance;
accountDTO.setBalance(actualBalance);
return accountDTO;
}
}
帐户服务:
public class AccountService {
@Autowired
AccountRepository accountRepository;
@Autowired
RequestBuilder requestBuilder;
@Autowired
CurrencyDTO currencyDTO;
@Cacheable("exchangeRates")
public Double getCurrencyValue(String currency) {
return currencyDTO.getCurrencyValue(currency);
}
public AccountDTO getAccountByIban(String iban){
AccountDTO accountDTO = null;
AccountEntity accountEntity = accountRepository.findByIban(iban);
if (accountEntity != null ) {
accountDTO = accountEntity.toDTO();
}
return accountDTO;
}
}
单元测试类:
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@SpringBootTest
public class AccountServiceTest {
@MockBean
AccountController accountController;
@Spy
@InjectMocks
AccountService accountService;
@Mock
AccountRepository accountRepository;
@Autowired
MockMvc mockMvc;
@Before
public void setup() throws Exception {
AccountEntity accountEntity = new AccountEntity();
accountEntity.setIban("RO06PORL4513558777471397");
accountEntity.setBalance(10000D);
accountEntity.setCurrency("RON");
Mockito.when(accountRepository.save(accountEntity)).thenReturn(accountEntity);
}
@Test
public void testAccountNotFound() throws Exception {
mockMvc.perform(get("/account/RO2E2"))
.andExpect(status().isNotFound());
//Assert.assertTrue(accountService.getAccountByIban("RO06PORL4513558777471397") == null);
AccountDTO:
public class AccountDTO {
@ApiModelProperty(notes = "Account ID",name="id",required=true,value="id")
private int id;
@ApiModelProperty(notes = "Account IBAN",name="iban",required=true,value="iban")
private String iban;
@ApiModelProperty(notes = "Account Currency",name="currency",required=true,value="currency")
private String currency;
@ApiModelProperty(notes = "Account Balance",name="balance",required=true,value="balance")
private Double balance;
@ApiModelProperty(notes = "Last Update",name="lastUpdate",required=true,value="lastUpdate")
private Date lastUpdate;
谁能帮我改正我的测试课?我看不出我做错了什么
【问题讨论】:
-
在此处添加断点 AccountEntity accountEntity = accountRepository.findByIban(iban); accountEntitiy 是 null 还是别的什么?
-
我有使用 C# 的
Moq的经验,而不是 Java 的Mockito,但是当您不指定行为时,自动模拟设置会返回什么?您是否需要手动告诉它默认返回 404,并且只为您在设置中指定的 iban 返回 200? -
请贴出 AccountNotFoundException 类的代码。
标签: java spring-boot unit-testing spring-mvc mockito