Hi, how this answer could work with Kotlin? I trie...
# announcements
p
Hi, how this answer could work with Kotlin? I tried with Consumer but it’s not being called. https://stackoverflow.com/a/49407513/2430555
t
this example is only valid if you used the java forEach function, which is highly unlikely in kotlin code. If your tested code just uses the normal kotlin forEach inline function, you can't mock it with mockito. But - like with your last question - mocking something like this is highly unusual and your desired test could probably be achieved differently.
I am doing something like this
RealmList
is
AbstractList<E>
and written in Java
I am not sure what Kotlin is doing, but when opening the
forEach
function, it points to the
forEach
from Kotlin.
I find I will nail this if I find the expected “type” for
(T) -> Unit
when(lastUsedPatients.forEach(any()).thenAnswer {}
could be nice too, I don’t see any problem to reimplement the
forEach
using
for loop
t
I don't think mocking the kotlin forEach function is possible, because it is an inline function. Unless called from Java, it doesn't even exist in compiled code.
p
oh… so there is no way to test my code?
I don’t mind to do workarounds or slow code…
I am in the same situation with
map
t
you can't change the behaviour of the forEach function, but that doesn't mean you can't test your code. mocking an iterator should still work
j
The code may be telling you that what you are trying to do isn't a good idea. Have you heard of "dont mock types you dont own"? Its quite a useful guide. Maybe use an adapter instead, then you will be able to make the adapter do whatever you want in tests.
p
@Tobias Berger Mocking the iterator is not working.
@James Richardson Since when I own the type?
t
in the code on that github issue you seeme to have a mocked user and you call forEach on the messages property of that user. Did you make sure that your mocked user provides a value for messages?
p
yes, it’s just an example, the messages list is not empty.
t
maybe you have some setup that iterates over your list multiple times. If you mock it with
thenReturn
(and not
thenAnswer
) this willl always get the same iterator instance which already reached the end of your list. I think if you want more detailed help, you need to provide a more detailed example that reproduces your issue
p
I will update the code in the issue
@Tobias Berger Example updated!
t
I really don't see your problem. I adapted your code just slightly so it actually compiles and it runs just fine, except for the thing I mentioned before about reusing the iterator instance which lets the second loop (the map call) just skip. Also I still don't get why you even bother to mock RealmList and User if you could just do
Copy code
val user = User(RealmList(message))
Sorry if I seem a bit rude here, I'm really just trying to help. But that's really hard if the error can't be reproduced
This is mocking the iterator() function and works just as expected
p
when(messages.iterator()).thenAnswer { messagesList.iterator() }
did the trick, is there any reason for this?
Thank you anyway!
t
an iterator is only good for going through the list once. Therefore you usually get a new one every time you call the
iterator()
function. If you mock that with
thenReturn(messageList.iterator())
, it will just call that once on messageList and reuse that iterator instance every time you try to get one for your mock. Once your first loop over this iterator is finished, it will always say it has no more items. With
thenAnswer
you define a supplier that is called each time your mocked function is used, providing a new iterator for each call (as would be expected)
❤️ 1