Mockk matching and overloaded function withArg - kotlin

Hello I am trying to find a way to match an overloaded function inside of the verify using withArg
The doc doesnt really point this out
every { getResponse.Ids } returns listOf(121212L)
assert( client.getExtIds(Ids) )
verify {
client.getExtIdsCall().call(
withArg {
assertEquals(GetExtIdsRequest.builder()
.withIds("foo")
.withType("bar")
.build().hashCode(), it.hashCode()
)
}
)
}
Something like above. But unfortunately I cant because the client.getExtIdsCall().call() accepts two different types of objects. One of which has the hashCode I want. So the it can not be referred correctly to call the hashCode function

You can resolve this by explicitly specifying the type parameter of function withArg, e.g. if you want your parameter to be a Long, you can write:
withArg<Long> { ... }

Related

What is the analogue of Mockito.verifyZeroInteractions(obj) in the Mockk library?

I want to switch to Mockk, but i cant find analogue of this method in Mockk
It doesn't work
verify (exactly = 0) { obj }
The way you are trying it, is missing the method or variable
verify (exactly = 0) { obj.something }
Using the exactly zero approach would require
confirmVerified(obj)
To be sure nothing else was called.
The exact equivalent would be:
verify { obj wasNot Called }

How to remove element from iterator if condition depends on property of the object the iterator is based on?

Let me elaborate:
I need to be able to iterate over a list of objects. Each of the objects has a property which is a list, and I have to check if that list contains any elements that are not in another list.
When I tried to do it by using nested for loops, it kept giving me concurrent modification exceptions, so I tried to use an iterator, but now I'm stuck, since if I make an iterator based on the list of objects, I can't access the individual object's properties to then iterate over.
Here's some example code of what I was trying to accomplish:
for (preference in preferencesWithRestaurant) {
for (restaurantID in preference.restaurantIDs) {
// One method I tried using
preferencesWithRestaurant.removeIf{ !listOfIds.contains(restaurantID) }
/* alternate method I tried using
if (!listOfIds.contains(restaurantID)) {
preferencesWithRestaurant.remove(preference)
}
*/
}
}
If you can replace the value of preferencesWithRestaurant or store the result in another variable then you can filter it:
preferencesWithRestaurant = preferencesWithRestaurant.filter { preference ->
preference.restaurantIDs.all { it in listOfIds }
}
Depending on the exact type of preferencesWithRestaurant you may need to convert it to the proper type, e.g. invoke toMutableList() at the end.
If you prefer to modify preferencesWithRestaurant in-place, then you can use retainAll() (thanks #Tenfour04):
preferencesWithRestaurant.retainAll { preference ->
preference.restaurantIDs.all { it in listOfIds }
}
Alternatively, you can keep your original approach, but use a mutable iterator to remove an item while iterating:
val iter = preferencesWithRestaurant.listIterator()
for (preference in iter) {
for (restaurantID in preference.restaurantIDs) {
if (!listOfIds.contains(restaurantID)) {
iter.remove()
break
}
}
}

Create empty IFutureEnumerable instance

I have a method which performs an NHibernate query, and returns the values as an IEnumerable<long>. It is running a future query so the result is actually of type IFutureEnumerable<long>.
public static IEnumerable<long> GetQueryResults(IEnumerable<long> idsToFilterOn)
{
if((idsToFilterOn == null) || !(idsToFilterOn.Any()))
{
return Enumerable.Empty<long>();
}
else
{
IQueryOver<MyTable> query = GenerateTheBigQuery(idsToFilterOn);
return query.Future<long>();
}
}
I want this result to return IFutureEnumerable<long>, but I still want to first check the parameters, and if I know the result will be empty I want to just return an empty value without running a query.
If I just change the return type to IFutureEnumerable<long>, the line of code that returns Enumerable.Empty<long>() generates a compiler error (Cannot implicitly convert type...)
Is there some static method like FutureEnumerable.Empty<long>() which generates an IFutureEnumerable that returns an empty list?
Looking at the code, there doesn't appear to be any native support for that concept. IFutureEnumerable is implemented by two types, one of which is deprecated and neither offer the notion of emptiness.
I suppose that leaves it up to you to create a type that implements IFutureEnumerable<T> that supports emptiness.

Kotlin map a string to another type?

In swift, I can do
"Some String".map { SomeObject($0) }
In kotlin it seems like the string is treated as a char array so the result is the map of each character. Is it possible to get similar behavior like the swift code I posted?
"Some String".map { SomeObject(it) }
You can accomplish something like that with let:
"Some String".let { SomeObject(it) }
If you have an appropriate constructor in place (e.g. constructor(s : String) : this(...)) you can also call it as follows:
"Some String".let(::SomeObject)
run and with work also, but are usually taken if you want to rather call a method of the receiver on it. Using run/with for this would look as follows:
"Some String".run { SomeObject(this) }
with ("Some String") { SomeObject(this) }
// but run / with is rather useful for things like the following (where the shown function calls are functions of SomeObject):
val x = someObject.run {
doSomethingBefore()
returningSomethingElse()
}
Besides using let, run or with, you can also write an extension method:
fun String.toSomeObject() = SomeObject(this)
Then use it like follows:
"SomeObject".toSomeObject()

How do i check a count value in chai-as-promised?

I use cucumber and chai-as-promised as assertion library. What is the right way to check the count value. I use equal but it works only after converting string to integer.Is there a way to assert a integer value directly?
this.Then(/^the list should contain "([^"]*)" items$/, function (arg1, callback) {
var count=parseInt(arg1);
expect(element.all(by.repeater('item in list.items')).count()).to.eventually.equal(count).and.notify(callback);
});
If you really wanted to, I believe you could bypass parseInt() by using Chai's satisfy() method and JavaScript coercion, as shown below. However, I personally prefer the method you are currently using as it is easier to understand and coercion can be tricky.
this.Then(/^the list should contain "([^"]*)" items$/, function (arg1, callback) {
expect(element.all(by.repeater('item in list.items')).count()).to.eventually.satisfy(function(count) { return count == arg1 } ).and.notify(callback);
});