hey, i have a situation where we want to use mock ...
# apollo-kotlin
a
hey, i have a situation where we want to use mock data and construct them with mock values (custom scalars included) what we’ve had to do is do nasty workarounds like this:
Copy code
override fun resolveLeaf(context: FakeResolverContext): Any {
        val mergedField = context.mergedField
        val type = mergedField.type.rawType()
        if (type is CustomScalarType) {
            // workaround the fact that Apollo doesn't have an API for constructing adapters
            // so we dont need explicit dependencies constructed here.
            val adapter = __CustomScalarAdapters.responseAdapterFor<Any>(type)
            if (adapter is AdapterResolver<*, *> && type.className == adapter.outputClass.qualifiedName) {
                @Suppress("UNCHECKED_CAST")
                return (adapter as AdapterResolver<Any, Any>).convert(resolver.resolve(context, adapter.inputClass))
            }
        }

        return super.resolveLeaf(context)
    }
since the default fake resolver does not handle scalar types. should I file a feature request?
the workaround is making our custom scalar adapters implement interface to convert between things
Copy code
/**
 * Workaround for adapters not knowing how to construct their own types.
 */
interface AdapterResolver<Input : Any, Output : Any> {

    val inputClass: KClass<Input>

    val outputClass: KClass<Output>

    fun convert(input: Input): Output
}
m
Not sure I'm following. How do you get your initial mock data?
(in all case, if you already have an idea of an API that would help, please file a feature request!)
a
sure. we were using data builders to create mock data, returning the operation.data itself ourselves
passing in a `FakeResolver`:
Copy code
Someop.Data(resolver = resolver) {

}
to resolve things not explicitly filled in
we either need to manually provide any scalar field, or use the workaround
m
Do you want to create pseudo random scalars?
Apollo Kotlin knows nothing about the internal structure of the scalars nor how they are coerced so there's so much we can do there
Say you have a Date scalar, there has to be something that generates stuff like
2025-03-03T14:44:49Z
s
I have been trying something like this isn't that the intent of FakeRolver? And then constructing item like this:
Copy code
val dataResponse = SomeQuery.Data(DateTimeFakeResolver)
Copy code
object CustomFakeResolver : FakeResolver {
    override fun resolveLeaf(context: FakeResolverContext): Any {
        return when (val leafName = context.mergedField.type.rawType().name) {
            "DateTime" -> DateTimeFormatter.ISO_INSTANT.format(Instant.now())
            "String" -> DataGenerator.randomString()
            <... other stuff>
            else -> error("Don't know how to fake scalar: ${context} ${leafName}")
        }
    }

    override fun resolveListSize(context: FakeResolverContext): Int {
        return Random.nextInt(1, 3) // Generate 1–2 items for lists
    }

    override fun resolveMaybeNull(context: FakeResolverContext): Boolean {
        return false // Don't return nulls by default
    }

    override fun resolveTypename(context: FakeResolverContext): String {
        return context.id
    }

    override fun stableIdForObject(
        obj: Map<String, Any?>,
        mergedField: CompiledField
    ): String? {
        return null
    }
}