【发布时间】:2019-11-22 09:38:52
【问题描述】:
我有一个使用队列的简单命名服务:
@Named
class OrderFormService @Inject constructor(
private val repository: OrderFormRepository
) {
private val queue: Queue<OrderForm> = LinkedList()
private val logger: Logger = LoggerFactory.getLogger("service")
fun getNextOrderForm(input: GetNextOrderFormInput): GetNextOrderFormPayload? {
if (queue.isEmpty()) {
logger.info("queue is empty")
val forms: List<OrderForm> = repository.findTop1000ByImageTypeAndImageState(input.type, input.state)
forms.forEach {
queue.offer(it)
}
}
if (!queue.isEmpty()) {
return GetNextOrderFormPayload(queue.poll())
}
return null
}
}
在尝试对此进行单元测试时,我想模拟队列:
@ExtendWith(MockitoExtension::class)
internal class OrderFormServiceTest {
@Mock
private val queue: Queue<OrderForm> = LinkedList()
@Mock
lateinit var repository: OrderFormRepository
@InjectMocks
lateinit var service: OrderFormService
@Test
fun givenValidInputAndFilledQueueWhenGetNextOrderFormThenReturnPayload() {
// given
val expected = createOrderForm()
val expectedPayload = GetNextOrderFormPayload(expected)
given(queue.isEmpty()).willReturn(false)
given(queue.poll()).willReturn(expected)
// when
val input = GetNextOrderFormInput(ImageType.NUMBER, ImageState.UNCLASSIFIED)
val result = service.getNextOrderForm(input)
// then
assertThat(result).isEqualTo(expectedPayload)
}
}
但是队列总是空的。所以我猜队列没有被正确地嘲笑。我做错了什么?
编辑
我尝试过的事情:
- 使队列不是最终的:
...
var queue: Queue<OrderForm> = LinkedList()
...
- 使用
Mockito.mock:
...
var queue = Mockito.mock(Queue::class.java)
`when`(queue.isEmpty()).thenReturn(false)
`when`(queue.poll()).thenReturn(expected)
...
【问题讨论】:
-
绝对没有理由模拟队列,也就是说,顺便说一句,不是服务的注入依赖项。
-
不明白为什么不应该有理由模拟队列。我需要填充它来测试填充队列的行为。不嘲笑它:我应该如何填充它?而且因为它没有被注入,所以我不使用
@InjectedMock,而是使用@Mock -
所以,填写它。让你的模拟 repository.repository.findTop1000ByImageTypeAndImageState() 方法返回一个非空列表,调用 getNextOrderForm() 将填满队列。你的测试应该验证方法的约定,即方法的每次调用都返回集合的下一个元素,直到没有下一个元素,然后再次获取集合。
-
这完全不是我想要的。我已经介绍了那个测试用例。无需调用存储库即可填充队列。
-
不,不能。您发布的代码中唯一填充私有队列的位置是存储库返回的集合。
标签: kotlin junit mockito junit5