簡體   English   中英

循環內的Jasmine異步測試未按預期工作

[英]Jasmine async tests inside loop are not working as expected

我已經為使用Jasmine構建的node.js驅動的API編寫了一些單元測試。

測試工作正常,但是現在我想使用不同的輸入運行一組異步測試,但是我無法使其正常工作。

我的測試針對URL帶有“ offset”和“ limit”參數的API發出了一些請求,並且API在響應中(第一個,上一個,下一個和最后一個)插入了用於分頁的鏈接。

這是我的茉莉花測試:

describe('API with "limit" and "offset" parameters', function() {

    var offset = 0;
    var limit = 4;
    var url = baseUrl + '?limit=' + limit + '&offset=' + offset;

    beforeEach(function(done) {
        request.get(url, function(err, res, resBody) {
            response = res;
            body = JSON.parse(resBody);
            count = body.count;
            done();
        });
    });

    it('should respond with status code 200', function(done) {
        expect(response.statusCode).toEqual(200);
        done();
    });

    it('should have a response with [limit] results if count - offset >= limit, otherwise count - offset', function(done) {
        if(count - offset >= limit) expect(body.rows.length).toEqual(limit);
        else expect(body.rows.length).toEqual(count - offset);
        done();
    });

    it('should have navigation links', function(done) {
        expect(body.first).toBeDefined();
        expect(body.prev).toBeDefined();
        expect(body.next).toBeDefined();
        expect(body.last).toBeDefined();
        done();
    });

    it('should have "first" navigation link equal to url offset=0 and limit=limit', function(done) {
        expect(body.first).toEqual(baseUrl + '?limit=' + limit + '&offset=0');
        done();
    });

    it('should have "prev" navigation link equal to null if offset=0, otherwise offset = offset - limit', function(done) {
        if(offset ===0) expect(body.prev).toBeNull();
        else expect(body.prev).toEqual(baseUrl + '?limit=' + limit + '&offset=' + (offset - limit));
        done();
    });

    it('should have "next" navigation link equal to offset + limit, or null if offset+limit > count', function(done) {
        if(offset + limit <= count) expect(body.next).toEqual(baseUrl + '?limit=' + limit + '&offset=' + (offset + limit));
        else expect(body.next).toBeNull();
        done();
    });

    it('should have "last" navigation link equal to floor(count/limit)*limit', function(done) {
        expect(body.last).toEqual(baseUrl + '?limit=' + limit + '&offset=' + Math.floor(count/limit) * limit);
        done();
    });
});

此測試運行良好,但現在我想重復運行此測試,每次運行中將“偏移量”增加“限制”,直到到達最后一頁(即偏移量+限制> =計數),但我無法正常工作。

到目前為止我嘗試過的

我的第一個想法是將測試放入IIFE內的循環中,但這不起作用,因為for循環中的“計數”未定義(我猜它僅在“ it”內部可用):

for(var i=offset; i<count; i+=limit) {  // "count" is undefined here

        (function(offset, count, limit) {

            it('should have "first" navigation link equal to url offset=0 and limit=limit', function(done) {
                expect(body.first).toEqual(baseUrl + '?limit=' + limit + '&offset=0');
                done();
            });

            it('should have "prev" navigation link equal to null if offset=0, otherwise offset = offset - limit', function(done) {
                if(offset ===0) expect(body.prev).toBeNull();
                else expect(body.prev).toEqual(baseUrl + '?limit=' + limit + '&offset=' + (offset - limit));
                done();
            });

            it('should have "next" navigation link equal to offset + limit, or null if offset+limit > count', function(done) {
                if(offset + limit <= count) expect(body.next).toEqual(baseUrl + '?limit=' + limit + '&offset=' + (offset + limit));
                else expect(body.next).toBeNull();
                done();
            });

            it('should have "last" navigation link equal to floor(count/limit)*limit', function(done) {
                expect(body.last).toEqual(baseUrl + '?limit=' + limit + '&offset=' + Math.floor(count/limit) * limit);
                done();
            });
        })(offset, count, limit);
    }

我的第二個想法是在“ afterAll”內部進行遞增,再次將測試包裝在IIFE中。 似乎afterAll確實再次運行runTests()(我看到出現console.log),但是測試本身並未再次運行:

(function runTests(offset, count, limit) {
        console.log('running tests');
        beforeEach(function(done) {
            request.get(url, function(err, res, resBody) {
                response = res;
                body = JSON.parse(resBody);
                count = body.count;
                done();
            });
        });

        it('should have "first" navigation link equal to url offset=0 and limit=limit', function(done) {
            expect(body.first).toEqual(baseUrl + '?limit=' + limit + '&offset=0');
            done();
        });

        it('should have "prev" navigation link equal to null if offset=0, otherwise offset = offset - limit', function(done) {
            if(offset ===0) expect(body.prev).toBeNull();
            else expect(body.prev).toEqual(baseUrl + '?limit=' + limit + '&offset=' + (offset - limit));
            done();
        });

        it('should have "next" navigation link equal to offset + limit, or null if offset+limit > count', function(done) {
            console.log('next', offset, limit, count);
            if(offset + limit <= count) expect(body.next).toEqual(baseUrl + '?limit=' + limit + '&offset=' + (offset + limit));
            else expect(body.next).toBeNull();
            done();
        });

        it('should have "last" navigation link equal to floor(count/limit)*limit', function(done) {
            expect(body.last).toEqual(baseUrl + '?limit=' + limit + '&offset=' + Math.floor(count/limit) * limit);
            done();
        });

        afterAll(function() {
            offset += limit;

            if(offset < count) runTests(offset, count, limit);
        });
    })(offset, count, limit);

我在這里做錯了什么? 還有另一種方法可以使它工作嗎?

更新 :這是我基於Zlatko的答案的完整工作代碼:

describe('API with "limit" and "offset" parameters', function() {

    var offset = 0;
    var limit = 4;
    var url = baseUrl + '?limit=' + limit + '&offset=' + offset;

    function testNavLinks(limit, offset, url) {

        describe('Check navigation links with offset = ' + offset, function() {

            var response;
            var count;
            var body;

            beforeEach(function(done) {
                request.get(url, function(err, res, resBody) {
                    response = res;
                    body = JSON.parse(resBody);
                    count = body.count;
                    done();
                });
            });

            it('should respond with status code 200', function(done) {
                expect(response.statusCode).toEqual(200);
                done();
            });

            it('should have a response with [limit] results if count - offset >= limit, otherwise count - offset', function(done) {
                if(count - offset >= limit) expect(body.rows.length).toEqual(limit);
                else expect(body.rows.length).toEqual(count - offset);
                done();
            });

            it('should have navigation links', function(done) {
                expect(body.first).toBeDefined();
                expect(body.prev).toBeDefined();
                expect(body.next).toBeDefined();
                expect(body.last).toBeDefined();
                done();
            });

            it('should have "first" navigation link equal to url offset=0 and limit=limit', function(done) {
                expect(body.first).toEqual(baseUrl + '?limit=' + limit + '&offset=0');
                done();
            });

            it('should have "prev" navigation link equal to null if offset=0, otherwise offset = offset - limit', function(done) {
                if(offset === 0) expect(body.prev).toBeNull();
                else expect(body.prev).toEqual(baseUrl + '?limit=' + limit + '&offset=' + (offset - limit));
                done();
            });

            it('should have "next" navigation link equal to offset + limit, or null if offset+limit > count', function(done) {
                if(offset + limit <= count) expect(body.next).toEqual(baseUrl + '?limit=' + limit + '&offset=' + (offset + limit));
                else expect(body.next).toBeNull();
                done();
            });

            it('should have "last" navigation link equal to floor(count/limit)*limit', function(done) {
                expect(body.last).toEqual(baseUrl + '?limit=' + limit + '&offset=' + Math.floor(count/limit) * limit);
                done();
            });
        });
    }
    // 13 is the actual number of results
    // I did not manage to get the actual number from the response, see my comment below
    for(var i=0; i<13; i+=limit) {
        url = baseUrl + '?limit=' + limit + '&offset=' + i;
        testNavLinks(limit, i, url);
    }
});

因此,您嘗試多次重復測試,但是根本不需要處理IIFE。 只需使您的測試成為一個函數,然后從循環中調用它即可:

describe('Loop an async set of tests.', function() {

  var baseUrl = process.env.API_URL; // or whatever
  function loopMyApi(offset, limit) {

    // add a new suite
    describe('Calling at offset: ' + offset , function() {

      var response;
      var myUrl = baseUrl + '?limit=' + limit + '&offset=' + offset;
      beforeEach(function(done) {

        request(myUrl, function(err, res) {

          if (err) {throw err;}
          response = res;
          done();
        });
      });

      it('should have length', function() {

        // btw since response is already here, this test is now sync
        // no need for `done`.
        response.body.length.should.equal(limit);
      });
      it('should be ok', function() {
        response.statusCode.should.be.lessThan(399);
      });
    });
  }
  var limit = 10;
  // you can start like this, or just make a regular for
  // loop as you have in your examples.
  [0, 10, 20, 30].forEach(function(offset) {

    // if you want to modify limit for some reason, do it here.
    loopMyApi(offset, limit);
  });
});

根據需要進行調整以適合您的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM