acceptance test - addContextListerner stops test

iamable's Avatar

iamable

29 Apr, 2015 12:23 PM

Hey, I'm new to tobotlegs 2 and also new to unit tests.
I have to create an acceptance test for all my user stories.

Regarding the architecture:

I have a service receiving data from an external source and preparing the data for the model.
the model fires an event with the data as payload.
the mediator listens to event and triggering changing the view.

now I want to test the whole with setting the value in service and testing wether view is updating.

unfortunately after initializing the mediator the test seems to stop.
I know I have to create and pass an eventDispatcher.

This is the test:
''' private var telltalesService : TelltalesService;
private var eventDispatcher : IEventDispatcher; private var telltalesModel:TelltalesModel; private var telltaleView:TelltaleView; private var telltalesMediator:TelltaleMediator;

    [Before]
    public function setUp():void
    {
        telltalesService = new TelltalesService();
        telltalesModel = new TelltalesModel();
        eventDispatcher = new EventDispatcher();
        telltalesMediator = new TelltaleMediator();
        telltaleView = new TelltaleView();

        telltalesService.telltalesModel = telltalesModel;
        telltalesService.telltalesModel.eventDispatcher = eventDispatcher;

        telltalesMediator.view = telltaleView;
        telltalesMediator.eventDispatcher = eventDispatcher;
        telltalesMediator.initialize();
    }

    [Test]
    public function test_display_of_telltale_while_incoming_signal():void
    {
        telltalesService.highBeam = true;

        trace(telltalesModel.light_telltale);

        Assert.assertEquals(telltalesModel.light_telltale, telltaleView.getChildAt(0));
    }

'''

  1. Support Staff 1 Posted by Ondina D.F. on 30 Apr, 2015 09:09 AM

    Ondina D.F.'s Avatar

    Please look at Joel's example for robotlegs 2 to see how to mock a view and how to dispatch an event from a mock service:

    https://github.com/joelhooks/robotlegs-examples-FlickrGallery/blob/...

    The entire project + tests:
    https://github.com/joelhooks/robotlegs-examples-FlickrGallery

  2. Support Staff 2 Posted by Ondina D.F. on 30 Apr, 2015 10:25 AM

    Ondina D.F.'s Avatar

    I've just run Joel's tests and noticed that you need to make a few changes. He used an older version of robotlegs 2.

    For example in TestGalleryLabelMediation

    replace this:
    galleryLabelMediator.setViewComponent(galleryLabel);

    with this:
    galleryLabelMediator.viewComponent = galleryLabel;

    replace this:
    import robotlegs.bender.extensions.eventMap.impl.EventMap;

    with this:
    import robotlegs.bender.extensions.localEventMap.impl.EventMap;

    replace this:
    galleryLabelMediator.eventMap = new EventMap(dispatcher);

    with this:
    galleryLabelMediator.eventMap = new EventMap();

    You need to provide the mediator with an EventDispatcher and an EventMap

    telltalesMediator.eventMap = new EventMap();

  3. 3 Posted by iamable on 30 Apr, 2015 11:33 AM

    iamable's Avatar

    great thank you. It is working now!

    Thanks for helping me all the time.

  4. 4 Posted by iamable on 30 Apr, 2015 01:23 PM

    iamable's Avatar

    In another acceptance test I have another problem:

    The model is dispatching an event every 500ms. the mediator listens for it and changes the view based on a specific value from that model.

    How can I test this? I tried with async tests but I don't get it working.

    [Before] public function setUp():void { tubeService = new TubeService(); tubeModel = new TubeModel(); eventDispatcher = new EventDispatcher(); digitalSpeedMediator = new DigitalSpeedMediator(); digitalSpeedView = new DigitalSpeed();

            digitalSpeedMediator.view = digitalSpeedView;
            digitalSpeedMediator.viewComponent = digitalSpeedView;
            digitalSpeedMediator.eventDispatcher = eventDispatcher;
            digitalSpeedMediator.eventMap = new EventMap();
    
            tubeModel.eventDispatcher = eventDispatcher;
            tubeService.tubeModel = tubeModel;
    
            digitalSpeedMediator.initialize();
    
            timer = new Timer(2000, 1);
        }
    
        [After]
        public function tearDown():void
        {
            if (timer)
            {
                timer.stop();
            }
            timer = null;
        }
    
        [Test( async )]
        public function shouldCompleteTimer():void
        {
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, Async.asyncHandler(this, handleWin, 3000, timer, handleTimeout), false, 0, true);
            timer.repeatCount = 1;
            timer.start();
    

    // tubeService.vehicleSpeed = 10; }

        private function handleWin(e:TimerEvent):void
        {
            trace("erfolg");
            Assert.assertEquals("10", digitalSpeedView.digitalSpeed.textField.text);
        }
    
        protected function handleTimeout(passThroughData:Object):void
        {
            trace("miss");
            Assert.fail("Pending event timed out");
        }
    
  5. Support Staff 5 Posted by Ondina D.F. on 30 Apr, 2015 03:12 PM

    Ondina D.F.'s Avatar

    You're welcome.

    The model is dispatching an event every 500ms.

    Where are you dispatching the event??
    You have a timer handler (handleWin), but you're not dispatching any event in there. So, dispatch your model's event from within a timer handler and see what happens.

    I think that you really need to read more about unit testing in general, and look at examples. Keywords for the search: TDD, unit test(ting), flexunit, testing

    Have you tried Joel's example? You can try to use a timer with his TestGalleryLabelMediation.

    There are only a few discussions about unit testing on this forum, and you should search for them and read them. But, actually, the topic of unit testing is out of the scope of this forum....
    Don't expect to get an answer to all your questions about testing ;)

    A few links here:
    http://knowledge.robotlegs.org/discussions/examples/24-flexunit-int...

  6. 6 Posted by iamable on 08 May, 2015 08:45 AM

    iamable's Avatar

    OK I got this asynch test working.

    now I have a problem with a robotlegs service and a dependency for the injector.

    [Inject] public var injector:IInjector;

    In test class how can I provide that dependency?
    How can I intsatiate that injector and pass it to the service?

  7. Support Staff 7 Posted by Ondina D.F. on 11 May, 2015 08:50 AM

    Ondina D.F.'s Avatar

    You need to provide the class under test with all its dependencies. You play the role of the Injector by creating an instance of every class that the Injector would normally inject into it.
    Also look at Mockolate (links below).

    If, for some reasons, you need the Injector itself, you have to instantiate it like this:

    private var injector:IInjector;
    injector = new RobotlegsInjector();

    or if you created an instance of the context, you'd have access to the injector like so:
    context.injector.

    Have you already looked at the links I gave you?

    Here, again, a few links that will help you learn TDD with Robotlegs:

    The Robotlegs Book + Examples with TESTS:

    ActionScript Developer's Guide to Robotlegs
    http://shop.oreilly.com/product/0636920021216.do

    https://github.com/Stray/robotlegs-examples-OreillyBook

    Mockolate: http://mockolate.org/

    Mock example:

    https://github.com/Stray/robotlegs-examples-OreillyBook/blob/master...

    The Robotlegs framework tests are a good inspiration:

    https://github.com/robotlegs/robotlegs-framework/tree/master/test
    https://github.com/robotlegs/robotlegs-framework/blob/master/test/r...

  8. Ondina D.F. closed this discussion on 02 Jun, 2015 08:48 AM.

  9. iamable re-opened this discussion on 16 Jun, 2015 10:13 AM

  10. 8 Posted by iamable on 16 Jun, 2015 10:13 AM

    iamable's Avatar

    Hello Ondina,

    private var injector:IInjector;
    injector = new RobotlegsInjector();

    that LOCs helped me with the problem where injector was null.

    Curently I try to test the factory we are discussing about in another post and there is also the injector injected because it should provide a singletons instance

    public function getTelltale(lightID:String):Light
    { return injector.getInstance(lightList[lightID]); }

    I provided new RobotlegsInjector to that factory but all the mappings are missing while running the test. Do I have to make all the mappings again in the test case?

  11. Support Staff 9 Posted by Ondina D.F. on 16 Jun, 2015 11:32 AM

    Ondina D.F.'s Avatar

    Hello,

    I gave you the example of instantiating the injector, because you asked how to do it. I didn't say to use it like this for testing your own classes. You would need the injector, if you would test the framework itself or a custom extension. But, for testing your application's classes, as I said in the first sentence of my previous message, you have to provide the class under test with its dependencies. You are the one instantiating these dependencies. You don't need the injector, because you are doing its job:
    var someDependency:SomeDependency = new SomeDependency();

    I've already given you a few links.
    Have you looked at the examples and tests from the Robotlegs book ???

    https://github.com/Stray/robotlegs-examples-OreillyBook/tree/master...
    https://github.com/Stray/robotlegs-examples-OreillyBook/tree/master...

    Look at the class:

    https://github.com/Stray/robotlegs-examples-OreillyBook/blob/master...

    and then to its test:

    https://github.com/Stray/robotlegs-examples-OreillyBook/blob/master...

    See the injections into SQLTaskService ?

    [Inject]
    public var statusListModel:StatusListModel;
    
    [Inject]
    public var taskListModel:TaskListModel;
    

    Now, in the test class, YOU're instantiating StatusListModel and TaskListModel YOURSELF:

    [Before(async)]
    public function setup():void
    {
        taskService = new SQLTaskService();
        taskService.statusListModel = new StatusListModel();
        taskService.taskListModel = new TaskListModel();
        initializeModels();
        prepareMockolates();
    }
    
  12. 10 Posted by iamable on 16 Jun, 2015 11:52 AM

    iamable's Avatar

    Yes I understand I have to provide the classes which were injected.
    Thatswhy a provided a new RobotlegsInjector.

    I really don't understand how I should test a method like this without providing an injector:

    public function getTelltale(telltaleID:String):Telltale
    { return injector.getInstance(telltaleList[telltaleID]); }

    at several points in my application I have to test if the factory return the right object.

    Sorry if my question is stupid.

  13. Support Staff 11 Posted by Ondina D.F. on 16 Jun, 2015 12:26 PM

    Ondina D.F.'s Avatar

    Yes I understand I have to provide the classes which were injected. Thatswhy a provided a new RobotlegsInjector.

    Well, obviously you didn't understand what I said :)
    SqlTaskServiceTest demonstrates how to provide SQLTaskService with its dependencies.
    I don't know how to explain this more clearly without going into lots of details about testing in general. I don't have time for this, and besides the focus of this forum is not on testing. I know from my own experience that learning how to write good tests is a painful process, so I understand what you are going through, but I can't help you.

    Sorry if my question is stupid.

    Your question is not stupid, but you need to read more about TDD in general and to work with the examples that I mentioned. Maybe reading the robotlegs book will also help you.

    Please read about mockolate, and please read these discussions:

    http://knowledge.robotlegs.org/discussions/problems/20-how-to-test-...

    http://knowledge.robotlegs.org/discussions/questions/241-unitintegr...

    http://knowledge.robotlegs.org/discussions/questions/843-1st-projec...

    http://knowledge.robotlegs.org/discussions/questions/239-examples-o...

    http://knowledge.robotlegs.org/discussions/questions/346-unit-testi...

    http://knowledge.robotlegs.org/discussions/questions/29-how-to-test...

  14. 12 Posted by iamable on 16 Jun, 2015 01:58 PM

    iamable's Avatar

    I'm so sorry. I don't want to waste your time.

    But please lets try to solve it :(

    my factory is injecting the IInjector which provides instances of objects which are mapped as signleton.
    so the factory has the injector as a dependency, right?
    You told me I have to provide the dependency: Thatswhy I created a new instance of the injector.
    Then the mapping is missing.

    Now I added the mapping to the new injector and the test works pretty well.

    But you told me I shouldn't instantiate injector in the test because this is done for testing the framework itself. I don't want to test the framework. So I am a little bit confused.
    Is it wrong to test that factory because I am using the injector to provide some instances?

  15. Support Staff 13 Posted by Ondina D.F. on 16 Jun, 2015 03:09 PM

    Ondina D.F.'s Avatar

    But you told me I shouldn't instantiate injector in the test because this is done for testing the framework itself.

    Sorry, I misunderstood your question. I thought you wanted to instantiate the injector only in your tests to be able to provide dependencies. Now I understand that you are injecting the injector into the real factory class. In this case, you are right, you have to provide the mapping as well.

  16. 14 Posted by iamable on 16 Jun, 2015 05:41 PM

    iamable's Avatar

    ok thank you for your time.

  17. Support Staff 15 Posted by Ondina D.F. on 18 Jun, 2015 08:17 AM

    Ondina D.F.'s Avatar

    no problem:)

  18. Ondina D.F. closed this discussion on 18 Jun, 2015 08:17 AM.

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

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac