Mockito测试:void方法第3次调用时抛出RuntimeException的问题
解锁门多次失败锁定逻辑的测试问题
业务代码实现
DoorServiceEjb 服务类
@Stateless(name = "DoorServiceEjb") public class DoorServiceEjb { private static final int EXPIRY_PERIOD = 1; private static final int MAX_ATTEMPTS = 3; private LoadingCache<String, Integer> attemptsCache; public DoorServiceEjb() { super(); attemptsCache = CacheBuilder .newBuilder() .expireAfterWrite(EXPIRY_PERIOD, TimeUnit.MINUTES) .build(new CacheLoader<String, Integer>() { @Override public Integer load(String key) throws Exception { return 0; } } ); } public boolean isLockedOut(String key) { try { boolean returnValue = attemptsCache.get(key) >= MAX_ATTEMPTS; return returnValue; } catch (ExecutionException e) { return false; } } }
Door 业务类
public class Door { @EJB(beanName = "DoorServiceEjb") private DoorServiceEjb doorServiceEjb; public void unlock(String user) { if (doorServiceEjb.isLockedOut(user)) { throw new RuntimeException("Locked"); } // Do something else } }
需求
当用户调用unlock()方法3次及以上时,该方法需抛出带有Locked消息的RuntimeException。
测试方案疑问与问题
我编写了如下测试用例,但不确定是否符合规范。我一直认为断言和验证应该针对@InjectMocks标注的被测对象,@Mock仅用于模拟被测对象的内部依赖。但我的测试中完全未使用@InjectMocks,反而对@Mock标注的Door对象进行验证和断言,且最终断言失败——捕获到的异常消息为null,而非预期的Locked。
测试代码
@ExtendWith(MockitoExtension.class) public class DoorTest { @Mock private Door door; @Test public void test_3FailedUnlockAttempts_ShouldLock() { Mockito.doNothing().doNothing().doThrow(RuntimeException.class).when(door).unlock(anyString()); door.unlock(anyString()); door.unlock(anyString()); RuntimeException exception = assertThrows(RuntimeException.class, () -> { door.unlock(anyString()); // should throw RuntimeException }); Mockito.verify(door, times(3)).unlock(anyString()); // 断言失败:异常消息为null,而非"Locked" Assertions.assertTrue(exception.getMessage().contains("Locked")); } }
内容的提问来源于stack exchange,提问作者pixel
相关产品推荐
相关产品推荐

