這是我參與更文挑戰的第20天,活動詳情查看: 更文挑戰java
上一篇文章咱們學習了,Drools規則約束的測試方法。今天咱們來學習ConstraintStream
方式的規則測試。話很少說,咱們來開始學習。markdown
ConstraintStream
包括Constraint Verifier
單元測試線束。要使用它,首先添加一個optaplanner-test.jar
。框架
咱們以N皇后
爲例子:dom
protected Constraint horizontalConflict(ConstraintFactory factory) {
return factory
.fromUniquePair(Queen.class, equal(Queen::getRowIndex))
.penalize("Horizontal conflict", SimpleScore.ONE);
}
複製代碼
下面的例子使用ConstraintVerifier API
來爲前面的約束流建立一個簡單的單元測試:ide
private ConstraintVerifier<NQueensConstraintProvider, NQueens> constraintVerifier
= ConstraintVerifier.build(new NQueensConstraintProvider(), NQueens.class, Queen.class);
@Test
public void horizontalConflictWithTwoQueens() {
Row row1 = new Row(0);
Column column1 = new Column(0);
Column column2 = new Column(1);
Queen queen1 = new Queen(0, row1, column1);
Queen queen2 = new Queen(1, row1, column2);
constraintVerifier.verifyThat(NQueensConstraintProvider::horizontalConflict)
.given(queen1, queen2)
.penalizesBy(1);
}
複製代碼
這個測試確保當同一行有兩個皇后時,horizontalConflict
約束會分配一個1的懲罰。下面一行建立了一個共享的ConstraintVerifier
實例,並用NQueensConstraintProvider
初始化了該實例。函數
private ConstraintVerifier<NQueensConstraintProvider, NQueens> constraintVerifier
= ConstraintVerifier.build(new NQueensConstraintProvider(), NQueens.class, Queen.class);
複製代碼
@Test
註解表示該方法是你選擇的測試框架中的單元測試。Constraint Verifier
與許多測試框架一塊兒工做,包括JUnit和AssertJ。post
測試的第一部分是準備測試數據。在這種狀況下,測試數據包括皇后計劃實體的兩個實例和它們的依賴關係(row、column)。單元測試
Row row1 = new Row(0);
Column column1 = new Column(0);
Column column2 = new Column(1);
Queen queen1 = new Queen(0, row1, column1);
Queen queen2 = new Queen(1, row1, column2);
複製代碼
再往下看,下面的代碼是測試約束條件的:學習
constraintVerifier.verifyThat(NQueensConstraintProvider::horizontalConflict)
.given(queen1, queen2)
.penalizesBy(1);
複製代碼
verifyThat()
調用是用來指定被測試的NQueensConstraintProvider
類的一個方法。這個方法必須對測試類可見,Java編譯器將強制執行。測試
given()
調用是用來列舉約束流將操做的全部事實。在本例中,given()
調用採用先前建立的queen1
和queen2
實例。另外,你也能夠在這裏使用givenSolution()
方法,提供一個規劃的解決方案。
最後,policizesBy()
調用完成測試,確保水平衝突約束,給定一個Queen
,結果是1的懲罰。這個數字是約束流中定義的匹配權重乘以匹配數的score
。
另外,你可使用rewardsWith()
調用來檢查獎勵而不是懲罰。這裏使用的方法取決於相關的約束流是以懲罰仍是以獎勵構建塊來終止的。
除了測試單個約束以外,還能夠測試整個ConstraintProvider
實例。考慮一下下面的測試:
@Test
public void givenFactsMultipleConstraints() {
Queen queen1 = new Queen(0, row1, column1);
Queen queen2 = new Queen(1, row2, column2);
Queen queen3 = new Queen(2, row3, column3);
constraintVerifier.verifyThat()
.given(queen1, queen2, queen3)
.scores(SimpleScore.of(-3));
}
複製代碼
與前面的例子只有兩個明顯的不一樣。
首先,這裏的verifyThat()
調用不須要參數,表示整個ConstraintProvider
實例正在被測試。
第二,這裏使用了 scores()
方法,而不是 penalizesBy()
或 rewardsWith()
調用。該方法在給定的事實上運行ConstraintProvider
,並返回由給定事實產生的全部約束匹配的 **"分數 "**之和。
使用這個方法,能夠確保約束條件提供者不會遺漏任何約束條件,而且隨着你的代碼庫的發展,評分函數保持一致。
不匹配結果:
java.lang.AssertionError: Broken expectation.
Constraint: org.optaplanner.examples.nqueens.domain/Horizontal conflict
Expected penalty: 1 (class java.lang.Integer) Actual penalty: 0 (class java.lang.Integer) Explanation of score (0): Constraint match totals: 0: constraint (Horizontal conflict) has 0 matches: Indictments: at org.optaplanner.test.impl.score.stream.DefaultSingleConstraintAssertion.assertImpact(DefaultSingleConstraintAssertion.java:112) at org.optaplanner.test.impl.score.stream.DefaultSingleConstraintAssertion.penalizesBy(DefaultSingleConstraintAssertion.java:60) at org.optaplanner.t 複製代碼
正常的結果跟上一章的同樣。
經過這個例子,咱們學習了OptaPlanner如何測試ConstraintStream的約束規則,這對咱們來講很是的重要,由於你不會指望着在生產環境測試,或者本地須要一套完整的求解數據才能開始測試。
下一篇章咱們來學習如何查看約束評分的例子。
創做不易,禁止未受權的轉載。若是個人文章對您有幫助,就請點贊/收藏/關注鼓勵支持一下吧💕💕💕💕💕💕