2014-11-24 5 views
0

Я использую Stripe, чтобы получить информацию о кредитной карте пользователя, нашивка имеет функцию, которая будет делать запрос JSONP, чтобы сгенерировать маркер (https://stripe.com/docs/stripe.js)модульных тесты Karma для отложенного обещанию JSONP обратного вызова (stripe.js)

Я обернуть этот вызов внутри службы:

app.factory('payment', ['$window', '$q', function($window, $q) { 

    return { 
    /** 
    * Creates stripe token. This token will be send to our server. 
    * @see https://stripe.com/docs/tutorials/forms 
    * @param {Object} formData 
    * @param {Element} form 
    * @return {Promise} 
    */ 
    createStripeToken: function(formData, form) { 
     if (angular.isUndefined($window.Stripe)) { return; } 

     var deferred = $q.defer(); 

     Stripe.card.createToken(formData, function(status, response) { 
     console.log(status) // => no output in test 
     var error = response.error; 

     if(error) { 
      // use form to set validations 
      if(error.type === 'card_error') { 
      var formField = error.param; // 'cvc' 
      form[formField].$setValidity(error.code, false); 
      } 
      deferred.reject(); 
     } else { 
      // response contains id (token) and card, which contains additional card details 
      deferred.resolve(response); 
     } 
     }); 
     return deferred.promise; 
    } 
    }; 

}]); 

Все работает отлично, за исключением тестов, здесь я использую Stripe с нашим тестовым ключом API!

describe('Payment Service', function() { 
    var service; 
    var success, error; 

    beforeEach(inject(function (payment) { 
    service = payment; 
    })); 

    it('should get successful stripe response', function() { 
    var createTokenFn = spyOn(Stripe.card, 'createToken'); 
    // Stripe.card.createToken = jasmine.createSpy("createToken"); 

    var formData = { 
     number: '4111 1111 1111 1111', 
     cvc: '123', 
     exp_month: '12', 
     exp_year: '23' 
    }; 

    service.createStripeToken(formData, null).then(function(data) { 
     console.log('success') // => no output 
     success = data; 
    }, function(data) { 
     console.log('error') // => no output 
     error = data; 
    }); 

    $rootScope.$digest(); // $rootScope is loaded in my spec helper, this line makes no difference 

    expect(createTokenFn).toHaveBeenCalledWith(formData, jasmine.any(Function)); // success 
    expect(success).not.toEqual(undefined); // fail 
    }); 

}); 

Это правильный способ протестировать такую ​​услугу? И как я могу проверить, работает ли обратный вызов?

ответ

2

Вы можете получить обратный вызов, используя callFake, предоставленный шпионом.

var createTokenFn = spyOn(Stripe.card, 'createToken').andCallFake(function(formData, callback) { 
    callback(200, { error: undefined }); 
}); 

Затем вы можете изменить ответ, чтобы он соответствовал вашим различным вариантам использования.

Fiddle: http://jsfiddle.net/bbbuu37w/1/

Не знаю, если это какая-то польза для вас, но я наткнулся на тот lib который, кажется, является оболочкой для Strip.Js для угловой.

+0

Большое спасибо, что работает :) Вы знаете, как не заглушить ответ, но получить реальный ответ? Я знаю, что для stripe.js существует множество разных оболочек и модулей, но все они делают что-то по-другому, а некоторые не тестируются, поэтому я сделал свой собственный подход. –

+1

Предположим, что обратный вызов означает, что некоторые асинхронные обработки говорят о вызове http из библиотеки lib, поэтому вам нужно будет подключиться к нему, чтобы высмеять нужную вам часть. Объект ответа кажется достаточно документированным, и, вероятно, поддерживается таким образом, чтобы я полагался на это. В противном случае фактический ответ может означать фактический вызов, поэтому некоторые тесты интеграции с фактическим сервисом могут пригодиться. Но я склонен писать фасады или какую-то оболочку для библиотеки такого типа, чтобы тестировать поведение моего кода, а не стороннего для модульного тестирования. –

Смежные вопросы