wardbell / bardjs

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

Mock resolving promise #36

Closed bensinther closed 8 years ago

bensinther commented 8 years ago

First of all, thanks Ward for writing such a nice test helper lib.

UPDATE 19.05.2016

I have solved it now. The issue in general is, that I have two services, whereas the PostService has a dependency to Api. Order seems to be the problem here.

The solution is to first include the Api Service with all the other Dependencies other than PostService, mock the Api Service and then finally include the Post Service via another bard.inject().

beforeEach(function() {
                bard.appModule('testingApp');
                bard.inject('Api', '$rootScope', '$q', '$httpBackend'); //first include Api

                testData = [
                    "post1", "post2", "post3"
                ];

        //second mock the Api
                bard.mockService(Api, {
                    getPosts: $q.when(testData)
                });

                //third inject the PostService which has Api as a dependency
                bard.inject('PostService');

                $httpBackend.whenGET(/\.*./).respond({anything: 123});
            });

Updated Plnkr: http://plnkr.co/edit/cGEWQMKgaRhoATF4Q2zf?p=preview


I am currently trying to mock a resolving promise and test some code that is inside the .then function of a service. Without bard.js it is working, but when trying to do the same thing with bard.js it is not working, and I am not able to find the bug (maybe it is a bug on my side?!).

I have set up a plnkr which is including both test cases (w/ and w/o bard.js) http://plnkr.co/edit/f8tH7XAiLoxlGbQFxfIH?p=preview

First of all, I have two services: PostService and Api.

function PostService(Api) {

        var svc = this;

        svc.posts = null;

        ////////////////////////// Init

        init();

        function init() {
            Api.getPosts()
                .then(function(result) {
                    svc.posts = result;
                })
        }
    }
function Api($http) {

        var svc = this;
        var root = 'http://jsonplaceholder.typicode.com';

        // Functions

        svc.getPosts = getPosts;

        ////////////////////////// Implementation

        function getPosts() {
            return $http({
                method: 'GET',
                url: root + '/posts'
            })
        }
    }

My test case is very simple: first, check if the PostService.posts is null. Second, after a $rootScope.$apply() the promise should be resolved and the PostService.posts should be equal to my mocked resolved promise's result.

it('should initially set the posts to null', function() {
                expect(PostService.posts).toBeNull();
            });

            it('should resolve a promise correctly', function() {
                $rootScope.$apply();
                expect(PostService.posts).toEqual(testData);
            });

The none bard.js test setup looks like this (Test No. 1 inside the plnkr):

var mockApi, $rootScope, PostService, testData, $httpBackend;

            beforeEach(function() {
                mockApi = {};

                testData = {
                    "data": [1, 2, 3]
                };

                module('testingApp', function($provide) {
                    $provide.value('Api', mockApi);
                });

                inject(function($q) {
                    mockApi.getPosts = function() {
                        return $q.when(testData);
                    }
                });

            });

            beforeEach(inject(function(_$rootScope_, _PostService_, _$httpBackend_) {
                $rootScope = _$rootScope_;
                PostService = _PostService_;
                $httpBackend = _$httpBackend_;

                $httpBackend.whenGET(/http\.*/).respond({anything: 123});
            }));

Whereas the bard.js setup looks like this, but is failing with the error (Test No. 2 inside the plnkr)

Error: Expected null to equal [ 'post1', 'post2', 'post3' ].

var testData;

            beforeEach(function() {
                bard.appModule('testingApp');
                bard.inject('PostService', 'Api', '$rootScope', '$q', '$httpBackend');

                testData = [
                    "post1", "post2", "post3"
                ];

                bard.mockService(Api, {
                    getPosts: $q.when(testData) // also tried with function() { $q.when(testData) }) - no success
                });

                $httpBackend.whenGET(/\.*./).respond({anything: 123});
            });

Am I missing something or doing it wrong? Or can't his case be handled with the bard.js lib?

I also tried combining both test setups, debugged it, but didn't have success to get it working. I would like to use bard.js for promise testing as well.

It would be nice if we could get this fixed together, either on my side or inside the lib (I don't want to use the angular mock inject() underscore stuff :stuck_out_tongue_winking_eye: ) Thanks.