Control the application-domain in which mocks/proxy-classes are created

Create issue
Issue #36 open
Darren Bishop created an issue

I am currently experimenting with testing in a IoC-powered application e.g. with Parsley.

The testing approach involves wiring-up a number of components using DI and the aim is to verify that, while decoupled with messaging, these components can communicate and function as a collective correctly.

I would like to stub service calls with mockito-flex, but seeing as concrete-classes can not be stubbed, the alternative is to inject a mock into the IoC context.

This can be done as far as the API is concerned, but I experience the following error:

{{{ #!as3 ReferenceError: Specified ApplicationDomain does not contain the class asmock.generated::DirectoryService3AE89A3CA2BD79921B6AE4B863AB2635D393E7A6 at org.spicefactory.lib.reflect::ClassInfo$/getClassDefinitionByName()[I:\Spicefactory\Parsley\spicelib-reflect\org\spicefactory\lib\reflect\ClassInfo.as:150] at org.spicefactory.lib.reflect::ClassInfo$/getClassInfo()[I:\Spicefactory\Parsley\spicelib-reflect\org\spicefactory\lib\reflect\ClassInfo.as:160] at org.spicefactory.lib.reflect::ClassInfo$/forInstance()[I:\Spicefactory\Parsley\spicelib-reflect\org\spicefactory\lib\reflect\ClassInfo.as:117] at org.spicefactory.parsley.runtime.processor::RuntimeConfigurationProcessor/processInstances()[I:\Spicefactory\Parsley\parsley-config\org\spicefactory\parsley\runtime\processor\RuntimeConfigurationProcessor.as:85] at org.spicefactory.parsley.runtime.processor::RuntimeConfigurationProcessor/processConfiguration()[I:\Spicefactory\Parsley\parsley-config\org\spicefactory\parsley\runtime\processor\RuntimeConfigurationProcessor.as:78] at org.spicefactory.parsley.core.builder.impl::DefaultCompositeContextBuilder/handleProcessor()[I:\Spicefactory\Parsley\parsley-core\org\spicefactory\parsley\core\builder\impl\DefaultCompositeContextBuilder.as:229] at org.spicefactory.parsley.core.builder.impl::DefaultCompositeContextBuilder/invokeNextProcessor()[I:\Spicefactory\Parsley\parsley-core\org\spicefactory\parsley\core\builder\impl\DefaultCompositeContextBuilder.as:205] at org.spicefactory.parsley.core.builder.impl::DefaultCompositeContextBuilder/invokeNextProcessor()[I:\Spicefactory\Parsley\parsley-core\org\spicefactory\parsley\core\builder\impl\DefaultCompositeContextBuilder.as:215] at org.spicefactory.parsley.core.builder.impl::DefaultCompositeContextBuilder/build()[I:\Spicefactory\Parsley\parsley-core\org\spicefactory\parsley\core\builder\impl\DefaultCompositeContextBuilder.as:178] at com.darrenbishop.support.flexunit.parsley::BuildParsleyContext/buildContext()[C:\Dev\workspaces\flex\parsley-flexunit\src\test\flex\com\darrenbishop\support\flexunit\parsley\BuildParsleyContext.as:40] at com.darrenbishop.support.flexunit.parsley::BuildParsleyContext/evaluate()[C:\Dev\workspaces\flex\parsley-flexunit\src\test\flex\com\darrenbishop\support\flexunit\parsley\BuildParsleyContext.as:26] at org.flexunit.internals.runners.statements::StatementSequencer/executeStep()[E:\hudson\jobs\FlexUnit4-Flex3.5\workspace\FlexUnit4\src\org\flexunit\internals\runners\statements\StatementSequencer.as:98] ... }}}

I believe there's a possible workaround in the MockeryProvider SPI mechanism, but seems quite heavy weight.

Is there a simpler way to do this?

Comments (5)

  1. loomis repo owner

    I think the problems lays somewhere in between what parsley reflection does and how asmock generates mock classes. As far as I'm concerned a mock class is loaded into the ApplicationDomain.currentDomain, possibly there is some discrepancy between this and the domain used by spicelib. You could try debugging a bit and make sure they are the same.

  2. Darren Bishop reporter

    Well I figured it out not long after my original post; it's not an issue with Parsley, which uses concrete classes and supports setting of the app-domain.

    The issue is somewhere in asMock; it creates a MovieClip on the fly and loads it dynamically and generates proxies there, so it's as if the mocks are coming from an in-memory SWF. Therefore mocks coming from that dynamic-SWF will have a different idea of what ApplicationDomain.currentDomain is.

    I worked around this by implementing my own MockeryProvider, MockCreator and ProxyRepository (asMock).

    Please see the files attached.

    These get hooked in by a modified MockitoRule implementation, as follows:

        override public function apply(base:IAsyncStatement, method:FrameworkMethod, test:Object):IAsyncStatement {
            ...
            currentMockito = new Mockito(AsmockADMockeryProvider);}}}
            ...
        }
    

    Note: the same can be done for MockitoRunner.

  3. loomis repo owner

    OK sounds good. I'll add something that allows setting the application domain. Thanks for figuring it out!

    Regards, Kris

  4. Log in to comment