最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why should I mock HTTP requests inside unit tests? - Stack Overflow

programmeradmin6浏览0评论

I'm working on a project and we've begun to write Jasmine unit tests. This application, like any good JS app does a lot of asynchronous fetching of data. I see that angular provides $httpBackend to mock up an HTTP request. I've also read and heard that it's a bad idea to test AJAX requests in your controller, and thus the raison d'etre for $httpBackend. Why is it not a good idea to test AJAX calls? How do big JS applications get around this fact? When does the actual testing of hitting the actual servers happen?

I'm working on a project and we've begun to write Jasmine unit tests. This application, like any good JS app does a lot of asynchronous fetching of data. I see that angular provides $httpBackend to mock up an HTTP request. I've also read and heard that it's a bad idea to test AJAX requests in your controller, and thus the raison d'etre for $httpBackend. Why is it not a good idea to test AJAX calls? How do big JS applications get around this fact? When does the actual testing of hitting the actual servers happen?

Share Improve this question edited Jun 13, 2014 at 1:23 Jonn 1,6741 gold badge16 silver badges26 bronze badges asked Jun 13, 2014 at 0:11 wootscootinboogiewootscootinboogie 8,71535 gold badges118 silver badges205 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 5

Asserting that you shouldn't be testing the server from Jasmine is an overly simple generalization. Whether you want small tests, large tests, or some bination of both really depends on the application. One might say that it isn't a "unit" test anymore - that it's an "integration" test - but those terms have been overloaded to the point of nonsense because it's a rather artificial dichotomy. Write tests that are useful and maintainable. Choosing the size of the test is an important part of that. What size is appropriate requires your own judgement of the situation.

The idea of a unit test is to outline how a small part of an application should work. If it is passing that test, you know that it is functioning as specified.

If you want to test a service that sends requests to your API, you set up unit tests that check the location/content/existence of the outgoing requests and verifies that it responds correctly to a valid response. To make the test as specific as possible though, it should not test anything outside of that little bubble.

Let's say we want to test this PersonService angular service:

app.service('PersonService', function ($q, $timeout, $http) {
    this.addPerson = function(data) {
        var deferred = $q.defer();
        $http.post('api/People', data).then(function(response) {
            deferred.resolve(response);
        });
        return deferred.promise;
    };
});

Here is a simple Jasmine test:

var service, $httpBackend;
beforeEach(module('app'));
beforeEach(inject(function(_PersonService_, _$httpBackend_) {
    service = _PersonService_;
    $httpBackend = _$httpBackend_;
}));

describe('addPerson', function() {
    var person;
    beforeEach(function() {
        // Make a person to send
        person = new Person({ id: "0ff1165f-7f75-45ed-8faa-ee94d874a1cf" });
    });

    afterEach(function() {
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });

    it('should send a person object to the API', function() {
        // setup
        var promise, expected, actual;
        expected = /* Whatever is sent back */
        $httpBackend.whenPOST('api/People', person)
            .respond(expected);

        // act
        promise = service.addPerson(person);
        promise.then(function(response) {
            actual = response.data;
        });

        $httpBackend.flush();

        // assert
        expect(actual).toEqual(expected);
    });
});

So we have a test that checks this very basic functionality (regardless of what the API actually does). This allows us to test pieces of the code individually---ie if the API is broken, your PersonService test won't break in addition to the related API test.

What you want to build to make sure everything works together properly is integration tests.

发布评论

评论列表(0)

  1. 暂无评论