forcedotcom / LightningTestingService

Apache License 2.0
122 stars 35 forks source link

How to mock Server actions with spyOn for doInit() #19

Closed rsoesemann closed 7 years ago

rsoesemann commented 7 years ago

I am trying to test a component with server actions call during doInit(). This is my spec:

describe('c:myComponent', function(){  
    it('renders stuff as expected', function(done) {
        $T.createComponent("c:myComponent", {}, document.getElementById("renderTestComponents"))
            .then(function(component) {
                // Setup
                spyOn($A, "enqueueAction").and.callFake(function(action) {
                    var cb = action.getCallback("SUCCESS")
                    cb.fn.apply(cb.s, [{ getState : function(){ return "SUCCESS"; }, 
                                            getReturnValue: function(){ return "a0DC000000vc03tMAA";} 
                                        }]
                                );
                });
            })
            // Verify
            .then(function(component) {
                expect(component.get("v.accounts").length).toBe(2);
                done();
            })
            .catch(function(e) {
                done.fail(e);
            });
    });
});

I am testing a component where doInit() uses Promises:

doInit: function(cmp, event, helper) {
   helper.callServer(cmp);
}

to call 2 helper methods which call server actions

callServer: function(cmp) {
        var action = cmp.get("c.serverAction");
action.setCallback(this, function(response) {
            cmp.set("v.accounts", response.getReturnValue());
        });
        $A.enqueueAction(action);
    }

I get obscure JS errors, so I thought maybe this is not the right way to do it. Can you provide an example on how to mock/stub initialisation?

esalman-sfdc commented 7 years ago

Jasmine's spies should work for actions enqueued as part of init. Just move the spy call higher up.

From Jasmine's doc "A spy only exists in the describe or it block in which it is defined"

For example, it(...., function(done){ spyOn.... $T.createComponent...... });

One side note: Aura team has a work-item to expose a method like action.getName(), which could be useful in making it easy for the spy to distinguish between if there happen to be multiple actions being enqueued (currently action has other platform exposed methods like getParam() which could be useful).

sjurgis commented 6 years ago

Hey @esalman-sfdc I can see getName() already working! Alternatively one can overwrite the spy, taken from StackOverflow:

$A.enqueueAction = jasmine.createSpy().and.callFake(function(action) {
          console.log(action.getParams());
        });