2015-01-27 19 views
6

Tôi đang xây dựng một mô-đun nút và đang cố gắng làm hết sức mình để kiểm tra thiết bị. Tôi đã thiết lập mocha và chai để làm việc kiểm tra xử lý. Tôi gặp sự cố khi thử nghiệm các phương thức không đồng bộ của mình (các phương thức trả về lời hứa).Xác nhận là đang phá vỡ chức năng Async trong Kiểm tra Mocha

Trong thử nghiệm sau, tôi đang thử nghiệm một phương thức trên đối tượng "Nâng cấp".

it('Should return a list of versions for the default git repo', function (done) { 
    fs.writeFileSync(appSetup.CONFIG_FILENAME, JSON.stringify(appSetup.DEFAULT_CONFIG)); 

    var upgrade = new Upgrade({ 
     quiet: true 
    }); 

    upgrade.getVersions().then(function (versions) { 
     assert(versions && versions.length > 0, 'Should have at least one version.'); 
     assert.equal(1, 2); // this throws the exception which causes the test case not even exist 
     done(); 
    }, done); 
    }); 

Cuộc gọi getVersions() trả về lời hứa là phương pháp không đồng bộ. Khi lời hứa giải quyết, tôi muốn kiểm tra giá trị được trả lại trong biến số versions.

assert(versions && versions.length > 0, 'Should have at least one version.'); là thử nghiệm thực tế. Tôi đã thêm assert.equal(1, 2); vì tôi nhận thấy rằng khi kiểm tra không thành công, trường hợp kiểm tra sẽ không hiển thị trong danh sách kiểm tra.

Tôi giả định rằng cuộc gọi khẳng định là ném một ngoại lệ mà Mocha sẽ nhận. Tuy nhiên nó đang bị mắc kẹt trong hàm xử lý lời hứa then.

Điều gì đang xảy ra ở đây? Tại sao khi khẳng định sẽ thất bại trong phương thức đó, nó không hiển thị trường hợp thử nghiệm trong danh sách (nó không hiển thị là không thành công; như nó không tồn tại)?

Trả lời

11

Cốt lõi của vấn đề là mã bạn có là chủ yếu:

try { 
    var versions = upgrade.getVersions(); 
} catch (err){ 
    return done(err); 
} 

assert(versions && versions.length > 0, 'Should have at least one version.'); 
assert.equal(1, 2); // this throws the exception which causes the test case not even exist 
done(); 

Nhìn vào đó, nó phải rõ ràng rằng nếu các xác nhận được ném, sau đó không phải là gọi lại sẽ chạy.

try { 
    var versions = upgrade.getVersions(); 
    assert(versions && versions.length > 0, 'Should have at least one version.'); 
    assert.equal(1, 2); // this throws the exception which causes the test case not even exist 
    done(); 
} catch (err){ 
    return done(err); 
} 

là giống như những gì bạn muốn, đó sẽ là:

upgrade.getVersions().then(function (versions) { 
    assert(versions && versions.length > 0, 'Should have at least one version.'); 
    assert.equal(1, 2); // this throws the exception which causes the test case not even exist 
}).then(done, done); 

Node rằng điều này sẽ thực hiện khẳng định và sau đó di chuyển callbacks thành một thứ .then() rằng sẽ luôn luôn xử lý các sai sót.

Điều đó nói rằng, nó sẽ dễ dàng hơn nhiều để chỉ đơn giản là trả lại lời hứa như

return upgrade.getVersions().then(function (versions) { 
    assert(versions && versions.length > 0, 'Should have at least one version.'); 
    assert.equal(1, 2); // this throws the exception which causes the test case not even exist 
}); 

để cho Mocha giám sát lời hứa của chính nó mà không gọi lại.

+0

Tôi không chắc mình hiểu tại sao câu trả lời này hoạt động. Mã ban đầu về cơ bản là: async(), sau đó (function() { ném lỗi mới(); // nếu dòng này ném, thì điều này chuyển đến trình xử lý .catch() done(); }) .catch (done) // register done() làm trình xử lý lỗi. Nếu lệnh throw xảy ra, lệnh 'done()' trong trình xử lý 'then()' không được thực thi, nhưng trình xử lý '.catch()' được gọi thay thế ... vẫn còn 'done'. –

+0

Rất tiếc, nhận xét không cho phép chặn mã và khóa sau 5 phút. Xin lỗi về định dạng crap: ( –

+0

'.then (fn, done)' không tương đương với '.then (fn) .catch (done);', đó là cốt lõi của sự khác biệt. Đầu tiên nếu 'fn' ném , đó là một lỗi không được giải quyết, trong ví dụ thứ hai, 'done' được gọi là – loganfsmyth

4

Kiểm tra không hiển thị trong danh sách cho đến khi bạn gọi lại, điều này không bao giờ xảy ra nếu xác nhận đó không thành công. Bạn sẽ cần gọi số .catch(done) trên lời hứa cuối cùng để đảm bảo done luôn được gọi.

Bài kiểm tra sẽ hiển thị nếu bạn cung cấp cho nó giá trị hết thời gian mà bạn có thể nên làm.

Tất cả những gì đã nói, mocha hiểu lời hứa. Bạn không cần phải đối phó với callbacks tại tất cả:

it('Should return a list of versions for the default git repo', function() { 
    fs.writeFileSync(appSetup.CONFIG_FILENAME, JSON.stringify(appSetup.DEFAULT_CONFIG)); 

    var upgrade = new Upgrade({ 
     quiet: true 
    }); 

    return upgrade.getVersions().then(function (versions) { 
     assert(versions && versions.length > 0, 'Should have at least one version.'); 
     assert.equal(1, 2); 
    }); 
    }); 
+0

Tôi ước tôi có thể chấp nhận cả hai câu trả lời của bạn! –

Các vấn đề liên quan