mock测试使用断言_使用自定义断言丰富测试代码
mock測試使用斷言
受GeeCON會議期間@tkaczanowski演講的啟發,我決定仔細研究AssertJ庫的自定義斷言。
在我的“骰子”游戲中,我創建了一個“機會”,它是骰子的任何組合,其分數是所有骰子的總和。 這是相對簡單的對象:
在我的測試中,我想看看如何計算不同骰子組合的分數。 我從簡單開始(實際上只有一個):
public class ChanceTest {private Chance chance = new Chance();@Test@Parameterspublic void chance(Collection<Dice> rolled, int scoreValue) {// arrangeCollection<Dice> rolled = dice(1, 1, 3, 3, 3);// actScore score = chance.getScore(rolled);// assertassertThat(actualScore.getScorable()).isNotNull();assertThat(actualScore.getValue()).isEqualTo(expectedScoreValue);assertThat(actualScore.getReminder()).isEmpty();assertThat(actualScore.getCombination()).isEqualTo(rolled);}}測試中驗證了單個概念(得分對象)。 為了提高分數驗證的可讀性和可重用性,我將創建一個自定義斷言。 我希望我的斷言像其他任何AssertJ斷言一樣被使用,如下所示:
public class ChanceTest {private Chance chance = new Chance();@Testpublic void scoreIsSumOfAllDice() {Collection<Dice> rolled = dice(1, 1, 3, 3, 3);Score score = chance.getScore(rolled);ScoreAssertion.assertThat(score).hasValue(11).hasNoReminder().hasCombination(rolled);} }為了實現這一點,我需要創建一個從org.assertj.core.api.AbstractAssert擴展的ScoreAssertion類。 該類應具有公共靜態工廠方法和所有必需的驗證方法。 最后,實現可能如下圖所示。
class ScoreAssertion extends AbstractAssert<ScoreAssertion, Score> {protected ScoreAssertion(Score actual) {super(actual, ScoreAssertion.class);}public static ScoreAssertion assertThat(Score actual) {return new ScoreAssertion(actual);}public ScoreAssertion hasEmptyReminder() {isNotNull();if (!actual.getReminder().isEmpty()) {failWithMessage("Reminder is not empty");}return this;}public ScoreAssertion hasValue(int scoreValue) {isNotNull();if (actual.getValue() != scoreValue) {failWithMessage("Expected score to be <%s>, but was <%s>", scoreValue, actual.getValue());}return this;}public ScoreAssertion hasCombination(Collection<Dice> expected) {Assertions.assertThat(actual.getCombination()).containsExactly(expected.toArray(new Dice[0]));return this;} }創建這樣的斷言的動機是擁有更多可讀性和可重用性的代碼。 但這要付出一些代價–需要創建更多代碼。 在我的示例中,我知道我很快就會創建更多Scorables并且需要驗證它們的評分算法,因此創建附加代碼是合理的。 增益將可見。 例如,我創建了一個NumberInARow類,該類計算給定骰子組合中所有連續數字的分數。 分數是具有給定值的所有骰子的總和:
class NumberInARow implements Scorable {private final int number;public NumberInARow(int number) {this.number = number;}@Overridepublic Score getScore(Collection<Dice> dice) {Collection<Dice> combination = dice.stream().filter(value -> value.getValue() == number).collect(Collectors.toList());int scoreValue = combination.stream().mapToInt(value -> value.getValue()).sum();Collection<Dice> reminder = dice.stream().filter(value -> value.getValue() != number).collect(Collectors.toList());return Score.scoreBuilder(this).withValue(scoreValue).withReminder(reminder).withCombination(combination).build();} }我從連續檢查兩個5的測試開始,但是我已經錯過了斷言( hasReminder ,因此改進了ScoreAssertion 。 我繼續用其他測試更改斷言,直到獲得可以在測試中使用的非常完善的DSL:
public class NumberInARowTest {@Testpublic void twoFivesInARow() {NumberInARow numberInARow = new NumberInARow(5);Collection<Dice> dice = dice(1, 2, 3, 4, 5, 5);Score score = numberInARow.getScore(dice);// static import ScoreAssertionassertThat(score).hasValue(10).hasCombination(dice(5, 5)).hasReminder(dice(1, 2, 3, 4));}@Testpublic void noNumbersInARow() {NumberInARow numberInARow = new NumberInARow(5);Collection<Dice> dice = dice(1, 2, 3);Score score = numberInARow.getScore(dice);assertThat(score).isZero().hasReminder(dice(1, 2, 3));} }public class TwoPairsTest {@Testpublic void twoDistinctPairs() {TwoPairs twoPairs = new TwoPairs();Collection<Dice> dice = dice(2, 2, 3, 3, 1, 4);Score score = twoPairs.getScore(dice);assertThat(score).hasValue(10).hasCombination(dice(2, 2, 3, 3)).hasReminder(dice(1, 4));} }更改后的斷言如下所示:
class ScoreAssertion extends AbstractAssert<ScoreAssertion, Score> {protected ScoreAssertion(Score actual) {super(actual, ScoreAssertion.class);}public static ScoreAssertion assertThat(Score actual) {return new ScoreAssertion(actual);}public ScoreAssertion isZero() {hasValue(Score.ZERO);hasNoCombination();return this;}public ScoreAssertion hasValue(int scoreValue) {isNotNull();if (actual.getValue() != scoreValue) {failWithMessage("Expected score to be <%s>, but was <%s>",scoreValue, actual.getValue());}return this;}public ScoreAssertion hasNoReminder() {isNotNull();if (!actual.getReminder().isEmpty()) {failWithMessage("Reminder is not empty");}return this;}public ScoreAssertion hasReminder(Collection<Dice> expected) {isNotNull();Assertions.assertThat(actual.getReminder()).containsExactly(expected.toArray(new Dice[0]));return this;}private ScoreAssertion hasNoCombination() {isNotNull();if (!actual.getCombination().isEmpty()) {failWithMessage("Combination is not empty");}return this;}public ScoreAssertion hasCombination(Collection<Dice> expected) {isNotNull();Assertions.assertThat(actual.getCombination()).containsExactly(expected.toArray(new Dice[0]));return this;} }我真的很喜歡自定義AssertJ斷言的想法。 在某些情況下,它們將提高我的代碼的可讀性。 另一方面,我很確定不能在所有情況下都使用它們。 尤其是在那些可重用機會很小的地方。 在這種情況下,可以使用帶有分組斷言的私有方法。
你有什么意見?
資源資源
- https://github.com/joel-costigliola/assertj-core/wiki/Creating-specific-assertions
- @tkaczanowski的斷言演變
翻譯自: https://www.javacodegeeks.com/2014/05/spice-up-your-test-code-with-custom-assertions.html
mock測試使用斷言
總結
以上是生活随笔為你收集整理的mock测试使用断言_使用自定义断言丰富测试代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 世纪凤凰城备案价(风凰城备案价)
- 下一篇: Linux包(linux包下载)