Unit/Integration testing tips? Possibly loading a testing context file?

rickcr's Avatar

rickcr

10 Aug, 2010 03:20 PM via web

So far I've been pretty lazy and not set up unit tests within the Flex tier of my application.

I was looking at the FlickrImageGallery as an example of how to set up some unit tests for RL, but I have a few questions:

  • The flexunit tests in that example often use a setUp method in the mediator tests that manually creates an instance of the real Mediator. Then, in that same setup method, it calls the onRegister of the mediator. My problem is that in some of my onRegister implementations I'm dispatching an event that will end up triggering an http service call to return some data. I'd think I'd need a good way to load a context file that has my dummy services classes so they are the ones triggered when onRegister fires. The Flickr example doesn't really do this. In fact it seems to create everything in isolation in the unit tests without a context file -which has me wondering how that would work for things like models etc that are often in my Events or Services which need to be set with data in order to work. Without the context file in the unit tests how would the mapped Singletons even be there since they need to be injected? I guess I'd have to manually create them all and set them on the instances that need them... which is possible 'some' of the time... but if you call something that ends up trigger a few other events to fire how would those events be set with the correct singleton models without the framework to help?

  • What are some ways you guys implement unit/integration tests within robot legs? It would seem like the ideal would be that you could swap out a context file when running your tests (I'm currently using FlexMojos so I might have some power there to handle this with some maven filters?) In a java web app this is often handled through DI where when the unit tests start a different config file is used to provide the testing implementations of your interfaces. Do any of you take a similar approach when testing your RL apps?

  • I'm open to any suggestions/comments on best practices/practical things etc when it comes to testing the flex layer - since this is a new area that I'm working in.

  1. Support Staff 2 Posted by Joel Hooks on 10 Aug, 2010 03:35 PM

    Joel Hooks's Avatar

    The Flickr example doesn't really do this. In fact it seems to create everything in isolation in the unit tests without a context file

    That is what a unit test, testing a unit (a class in the case of OOP) in isolation. It isn't concerned about the service, the context, models, etc outside of how they are directly dependent of the unit under test. In most cases, I wouldn't have concrete versions of these dependencies at all. I'd use Mockolate and mock them for even great isolation and control.

    Without the context file in the unit tests how would the mapped Singletons even be there since they need to be injected?

    Unit tests are not concerned about mapping, singletons or otherwise. If your unit tests ARE using the framework or otherwise participate in the automated DI, you are off target for testing units in isolation and into the land of integration testing. Robotlegs is well tested, we don't need to test that the DI works or singleton mapping is enforced. You should manually create and supply dependencies.

    I'd have to manually create them all and set them on the instances that need them... which is possible 'some' of the time... but if you call something that ends up trigger a few other events to fire how would those events be set with the correct singleton models without the framework to help?

    Do the events trigger a command that updates the model? Frankly your mediator shouldn't have a care in the word after the event leaves its doorstep.

    This is when it is extremely pleasing to use interfaces for services and models. Your unit under test only knows that it has a contract, it doesn't care if that contract is fulfilled by a dummy, fake, mock or stub class.

    Take the mediator. You are concerned with a couple of things here. Does it listen for events? Does it dispatch events to the framework in response to events? You aren't concerned with the content of those events that is likely coming from other units (the view component, API on the model, etc) which would be tested separately from the mediator. Since a mediators job is extremely simple as a 'switch board' for a view component, it doesn't have a bunch of API to test to begin with.

    An approach here is to create a dummy or fake view component. To this end, I have taken to coding my view components to interfaces. It is a bit more 'verbose' with the classes (I have a lot more individual class/interface files), but I am able to get really fine-grained support when it comes to testing. I am able to exercise the interface contract of the view component in tests without having the weight of actually creating a UIComponent instance. Many times I simply mock them with Mockolate.

    It would seem like the ideal would be that you could swap out a context file when running your tests

    I don't think I can express strongly enough my opinion that unless you are actively testing the Context your unit tests should have no concept of the Context, Robotlegs, or the rest of the application.

  2. Support Staff 3 Posted by Joel Hooks on 10 Aug, 2010 03:36 PM

    Joel Hooks's Avatar

    I'll also add that I have a (rather long) tutorial rattling around in my head on this topic.

  3. 4 Posted by rickcr on 10 Aug, 2010 05:31 PM

    rickcr's Avatar

    I see what you're saying. I definitely wasn't thinking granular enough down to 'real' unit tests (I was definitely on the integration side of testing.)

    At first I was confused though since I thought even when setting up a unit test I'd run into trouble if my mediator onRegister dispatched and event, but I'm pretty sure It shouldn't matter. For example in an onRegister I have:

    //onRegister dispatch(new PromptCollectionsRetrieveEvent(PromptCollectionsRetrieveEvent.RETRIEVE_PROMPT_COLLECTIONS));

    The above shouldn't cause the unit test to fail when I happen to call

    myMediatorInstanceInATest.onRegister()

    since it will cause that dispatch to fire, but it won't matter since I don't care about testing that piece of the code at that time anyway ( the dispatch to retrieve prompt collections.)

  4. 5 Posted by Nikos on 02 Feb, 2011 04:12 PM

    Nikos's Avatar

    quote

    "This is when it is extremely pleasing to use interfaces for services and models. Your unit under test only knows that it has a contract, it doesn't care if that contract is fulfilled by a dummy, fake, mock or stub class."

    So how can you test the actual implementations of the classes under test (using the interface) if you are only using the interfaces in the test?

  5. 6 Posted by Stray on 02 Feb, 2011 04:21 PM

    Stray's Avatar

    This is really beyond the scope of robotlegs support. May I recommend 'Growing Object Oriented Software guided by Tests' as a starting point for learning about integration and end-to-end testing.

    The point though, is that you don't test the interfaces. You're testing the thing that *uses* the interfaces. For example - if a command is supposed to pull values from 2 different models, and based on the combination of values either call on one service or another, you can mock / stub the interfaces for all of those classes - 2 models and 2 services - specifically feed the test values and then confirm that the command called the right service passing the correct parameters.

    The Command is what is under test in this situation - not the interfaces of the injected objects it needs to do its work.

  6. Stray closed this discussion on 13 Feb, 2011 04:12 PM.

Comments are currently closed for this discussion. You can start a new one.