wardbell / bardjs

Spec helpers for testing angular v.1.x apps with Mocha, Jasmine and QUnit
MIT License
178 stars 34 forks source link

fakeStateProvider #15

Open zuzana opened 9 years ago

zuzana commented 9 years ago

I wonder about following piece of code in fakeStateProvider https://github.com/wardbell/bardjs/blob/master/dist/bard.js#L404-L407

// current: {},  // fake before each test as needed
// state:  {}  // fake before each test as needed
// more? You'll know when it fails :-)
_faked: 'this is the faked $state service'

How would I go about it, if I wanted e.g. fake state, current or sth. else. In my case I have get method that I'd like to fake (sinon.stub).

Thanks.

wardbell commented 9 years ago

Hmmm. Not terribly obvious is it.

Right now it simply stubs out everything in order to disable routing without blowing up.

My thought was that, you would inject $state into your test (perhaps in a beforeEach) and then monkey-patch as you need.

Here's what I had in mind:

    beforeEach(function() {
        // get fake $state router service
        bard.inject(this, '$state');

        // plug in fake $state router values for this set of tests
        $state.current = {/* fake values here */};
        $state.state = {/* fake values here */};
    })

I confess I haven't actually tried it. Perhaps you will be the first and give me some feedback :-)

wardbell commented 9 years ago

I released v.0.1.5 with these comments.

johnpapa commented 9 years ago

@zuzana does that answer your question?

zuzana commented 9 years ago

unfortunately not, the get function I would need to fake gets executed before I am able to inject because it is part of module.run.

I went around it like this:

beforeEach(function() {
    module('myApp.home', function($stateProvider){
        $stateProvider.$get = function() {
            return {
                get: sinon.stub()
            };
        };
    });
    bard.inject(this, '$controller', '$rootScope');
});

It might be useful to change the concatenation order in following code:

function appModule() {
    var args = Array.prototype.slice.call(arguments, 0);
    args = args.concat(fakeRouteHelperProvider, fakeRouteProvider,
                       fakeStateProvider, fakeToastr);
    return angular.mock.module.apply(angular.mock, args);
}

to

function appModule() {
    var args = Array.prototype.slice.call(arguments, 0);
    args = [fakeRouteHelperProvider, fakeRouteProvider,
                       fakeStateProvider, fakeToastr].concat(args);
    return angular.mock.module.apply(angular.mock, args);
}

so that way, if fakeStateProvider is not enough, I can override it with my own that has mocked properties I need.

bard.appModule('myApp.home', myFakeStateProvider);

But then again, appModule is meant to save lines, and since I'm adding to it my own fakers, then I better just use module.

wardbell commented 9 years ago

Chalk up another example of why I avoid module.run! It never gives you a chance to fake the run handler.

If I do need run, I make sure that anything substantive calls an injected service. Then I can fake that service and control its behavior and the run behavior indirectly.

Perhaps "avoid run" is a tip for the style guide.

FWIW, your approach of faking the stateProvider on your own is what I would do. The bard version wont help you and I don't think I can improve the bard version without making it more complex.

zuzana commented 9 years ago

ok, thanks for your responses, going to close this.

johnpapa commented 8 years ago

cc // @chintan-patel @johnpapa

gaelollivier commented 8 years ago

Why not changing the order of concatenation as @zuzana suggested ? That would allow to still use the faked services while being able to override them ?

johnpapa commented 8 years ago

I've avoided using bard.appModule for this reason. Wondering if we should just remove it @wardbell