0

Say I have a unit under test like this:

internal class MySerializer {
    fun serialize(): ByteArray {
        val initialBufferSize = 1000
        val autoResizeBuffer = true
        val value = ThirdPartySerializer(initialBufferSize, autoResizeBuffer)
        value.doMoreStuff()
        return value.serialize()
    }
}

How can I spy on ThirdPartySerializer, which comes from a 3rd-party library, to make sure that it's called with true as its second argument?

I normally test the outcome, not how functions are called, but in this case checking the constructor call is ideal: Otherwise, I'd have to write a test to make sure the output can be greater than 1000 bytes, which is problematic because "1000" constant can get out of sync and I wouldn't like to expose it as a public constant on the UUT so it can be used in its tests.

Gus
  • 1,132
  • 13
  • 21
  • Refactor `MySerializer` to pass `ThirdPartySerializer` and then provide the mock in the test. You could put `ThirdPartySerializer` as a field, or function parameter, or make a lambda like `(int,boolean) -> ThirdPartySerializer` – Neo Mar 05 '20 at 15:35

1 Answers1

1

I don't know of a way to do such a thing on the JVM.

However I don't see why you wouldn't just do

fun serialize(val initialBufferSize: Int = 1000): ByteArray {
    val autoResizeBuffer = true
    val value = ThirdPartySerializer(initialBufferSize, autoResizeBuffer)
    value.doMoreStuff()
    return value.serialize()
}

And then test the output size with whatever initial buffer size you'd like. This also results in you actually testing the behaviour instead of just assuming all will be ok as long as you pass this fabled 'true' value.

It also means that your tests won't need to be updated if the 3d party lib decides to change their external api or you decide to use a different library in your implementation. Your approach could even hide bugs if the meaning of the second argument is changed in a future release of the library.

somethingsomething
  • 1,746
  • 6
  • 8
  • I wanted to avoid changing the public API of my class just to make it possible to test its behaviour -- Users of that class should never have to worry/know about the initial buffer. Having said this, I think your proposed approach is probably the most elegant way to test that the internal buffer is resized. – Gus Mar 05 '20 at 16:23