2017-06-26 27 views
18
expect(true).to.be.true; 

Trong mã này, tất cả 'đến', 'be', 'true' có vẻ là thuộc tính của phản hồi đối tượng từ 'mong đợi (đúng)'.Dự kiến ​​(). To.be.true hoạt động như thế nào trong Chai?

Các thuộc tính này hoạt động như thế nào để chúng có thể tăng ngoại lệ?

+0

Tôi nghĩ rằng nó hoạt động thông qua (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__) giao diện javascript của [__defineGetter__' '] . –

+5

Nó hoạt động bởi vì họ đã thêm một loạt các thuộc tính giả mà không làm gì và chỉ thêm tiếng ồn. Tôi sẽ tranh luận 'assert.isTrue()' là dễ đọc hơn và chắc chắn sẽ không nhắc một câu hỏi như thế này. –

+1

@MattiVirkkunen Vâng, nếu mọi người muốn mã là * Tiếng Anh * và không * Tiếng Anh giống * Tôi nghĩ họ nên viết sách thay vì – cat

Trả lời

16

Bạn có thể kiểm tra mã nguồn:

[ 'to', 'be', 'been' 
    , 'is', 'and', 'has', 'have' 
    , 'with', 'that', 'which', 'at' 
    , 'of', 'same', 'but', 'does' ].forEach(function (chain) { 
    Assertion.addProperty(chain); 
}); 

và có một addProperty trong utils:
https://github.com/chaijs/chai/blob/master/lib/chai/utils/addProperty.js

Với điều này, bạn có thể chuỗi các thuộc tính vô hạn như: .to.be.to.to.to.be.equal()

Hãy tạo một cuộc biểu tình đơn giản:

Giả sử rằng bạn có một đối tượng assert, với .true() phương pháp

const assert = { 
    'true': function (v) { 
    return !!v 
    } 
} 

và bạn muốn để có thể chuỗi .to vô hạn. Đơn giản chỉ cần sử dụng các defineProperty để xác định getter của chúng tôi:

Object.defineProperty(assert, 'to', { 
    get() { 
    return assert 
    } 
}) 

vì vậy bây giờ bạn có thể

assert.to.to.to.to.true(false) 

đang làm việc: https://codepen.io/CodinCat/pen/LLzBEX?editors=0012


Tôi đã thêm một ví dụ khác phức tạp hơn ở đây: https://codepen.io/CodinCat/pen/dRVjXL?editors=0012

Trong ví dụ này, bạn có thể thấy tha t có một số hành vi trong thuộc tính .true.

Chúng tôi lưu trữ giá trị từ expect() trong nội bộ __expectObj và thuộc tính __value và sau đó xác minh nó trong bộ thu của .true. Vì vậy, bạn có thể

expect(false).to.to.to.to.true 
+1

Mã nơi 'true' là hàm không cần thiết, tôi chắc chắn OP biết cách viết hàm. Câu trả lời thực tế cho câu hỏi được ẩn đằng sau một liên kết; hãy di chuyển nó đến câu trả lời của bạn. –

+0

Vâng, trường hợp '.true' là thuộc tính (không phải là phương pháp) là điều tôi tò mò nhất. Tóm lại, có một hàm getter cho '.true' được kích hoạt khi tra cứu như trong' expect (false) .true', và hàm getter đó chạy test ... Wow, thú vị! –

7

Hãy xem nguồn của chai Assertion nhưng tl; dr là Chai thực hiện các phương pháp có thể chuỗi của riêng nó trên thư viện khẳng định của nó. Tuy nhiên, các từ khóa đặc biệt chỉ đơn giản là cú pháp đường như trong đoạn mã dưới đây cho thấy. Nghĩa họ chỉ là thuộc tính được thêm vào và có thể bị xiềng xích nhưng không thực sự được định nghĩa:

/** 
    * ### Language Chains 
    * 
    * The following are provided as chainable getters to improve the readability 
    * of your assertions. 
    * 
    * **Chains** 
    * 
    * - to 
    * - be 
    * - been 
    * - is 
    * - that 
    * - which 
    * - and 
    * - has 
    * - have 
    * - with 
    * - at 
    * - of 
    * - same 
    * - but 
    * - does 
    * 
    * @name language chains 
    * @namespace BDD 
    * @api public 
    */ 

    [ 'to', 'be', 'been' 
    , 'is', 'and', 'has', 'have' 
    , 'with', 'that', 'which', 'at' 
    , 'of', 'same', 'but', 'does' ].forEach(function (chain) { 
    Assertion.addProperty(chain); 
    }); 

Từ đó những gì nó thực sự trông cho được từ khóa đó đặc biệt định nghĩa. Vì vậy, một ví dụ là từ khóa .to.be.true nó sẽ nhìn vào true as defined trong đoạn mã dưới đây

/** 
    * ### .true 
    * 
    * Asserts that the target is strictly (`===`) equal to `true`. 
    * 
    *  expect(true).to.be.true; 
    * 
    * Add `.not` earlier in the chain to negate `.true`. However, it's often best 
    * to assert that the target is equal to its expected value, rather than not 
    * equal to `true`. 
    * 
    *  expect(false).to.be.false; // Recommended 
    *  expect(false).to.not.be.true; // Not recommended 
    * 
    *  expect(1).to.equal(1); // Recommended 
    *  expect(1).to.not.be.true; // Not recommended 
    * 
    * A custom error message can be given as the second argument to `expect`. 
    * 
    *  expect(false, 'nooo why fail??').to.be.true; 
    * 
    * @name true 
    * @namespace BDD 
    * @api public 
    */ 

    Assertion.addProperty('true', function() { 
    this.assert(
     true === flag(this, 'object') 
     , 'expected #{this} to be true' 
     , 'expected #{this} to be false' 
     , flag(this, 'negate') ? false : true 
    ); 
    }); 
Các vấn đề liên quan