Tuesday 9 July 2013

Weird issue with Mockbox and interfaces

G'day:
This is not gonna be a very well-realised article, as it's posing a question that I've not really been able to flesh out yet.


We use MXUnit and Mockbox for our unit testing. One of our tests - testMethodX() (not really) - is testing a method which internally calls a method (methodToMock()) from another CFC (My.cfc).

Like good little chickens we mock methodToMock(). The problem is that My.cfc implements SomeInterface.cfc, and sometimes testMethodX() errors when methodToMock() is called, with the following error:

Function argument mismatch.
The methodToMock function does not specify the same arguments or arguments in the same order in the My ColdFusion component and the SomeInterface ColdFusion interface.

coldfusion.runtime.InterfaceRuntimeExceptions$ArgumentsMistmatchException: Function argument mismatch. at
coldfusion.runtime.InterfaceRuntimeExceptions.throwArgumentsMistmatchException(InterfaceRuntimeExceptions.java:77) at
coldfusion.runtime.UDFMethod.verifyInterfaceMethodImpl(UDFMethod.java:611) at
coldfusion.runtime.TemplateProxy.verifyInterfaceMethodImpl(TemplateProxy.java:1025) at
coldfusion.runtime.TemplateProxy.verifyInterfaceImpl(TemplateProxy.java:1078) at [etc]

I understand the error, but I do not understand why I get it. The odd thing is that if we simply re-run the test, it's all OK. And continues to be OK.

We've isolated this down to only happening on the first test run for the life of the ColdFusion instance. IE: if I restart CF and run the test: it fails as per above. Thereafter it is fine. This is 100% replicable.

Update:

I have ported enough of our code across to Railo to be able to run this test, and can confirm the problem does not occur on Railo. So it seems to be a ColdFusion issue. Now I just need to contrive a repro case for it...

I have looked at the code that both Mockbox and MXUnit create as far as code stubs go, and they are identical for failing and passing tests. I've dumped out the metadata of the My.cfc instance when it errors, and it looks identical to how it should, and the method signature is fine.

I'm at a loss as to what else to look at to solve this. I doubt it's a Mockbox thing, I suspect it's a ColdFusion thing, but I cannot identify enough of the situation to be sure.

We're working around it cheekily at the moment... in beforeTests() I simply call the method which creates the mocked My.cfc and just don't use it. When it's then mocked again as part of the actual test, the second one works fine, and there's no error. This is adequate, but I'd like to understand what's going on.

I doubt anyone's had precisely this situation, but does the sort of thing that's happening sound familiar to anyone?

Cheers for any insight!

--
Adam