mock测试使用断言_使用自定义断言丰富测试代码
mock測試使用斷言
受GeeCON會議期間@tkaczanowski演講的啟發(fā),我決定仔細(xì)研究AssertJ庫的自定義斷言。
在我的“骰子”游戲中,我創(chuàng)建了一個“機(jī)會”,它是骰子的任何組合,其分?jǐn)?shù)是所有骰子的總和。 這是相對簡單的對象:
在我的測試中,我想看看如何計(jì)算不同骰子組合的分?jǐn)?shù)。 我從簡單開始(實(shí)際上只有一個):
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);}}測試中驗(yàn)證了單個概念(得分對象)。 為了提高分?jǐn)?shù)驗(yàn)證的可讀性和可重用性,我將創(chuàng)建一個自定義斷言。 我希望我的斷言像其他任何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);} }為了實(shí)現(xiàn)這一點(diǎn),我需要創(chuàng)建一個從org.assertj.core.api.AbstractAssert擴(kuò)展的ScoreAssertion類。 該類應(yīng)具有公共靜態(tài)工廠方法和所有必需的驗(yàn)證方法。 最后,實(shí)現(xiàn)可能如下圖所示。
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;} }創(chuàng)建這樣的斷言的動機(jī)是擁有更多可讀性和可重用性的代碼。 但這要付出一些代價–需要創(chuàng)建更多代碼。 在我的示例中,我知道我很快就會創(chuàng)建更多Scorables并且需要驗(yàn)證它們的評分算法,因此創(chuàng)建附加代碼是合理的。 增益將可見。 例如,我創(chuàng)建了一個NumberInARow類,該類計(jì)算給定骰子組合中所有連續(xù)數(shù)字的分?jǐn)?shù)。 分?jǐn)?shù)是具有給定值的所有骰子的總和:
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();} }我從連續(xù)檢查兩個5的測試開始,但是我已經(jīng)錯過了斷言( hasReminder ,因此改進(jìn)了ScoreAssertion 。 我繼續(xù)用其他測試更改斷言,直到獲得可以在測試中使用的非常完善的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斷言的想法。 在某些情況下,它們將提高我的代碼的可讀性。 另一方面,我很確定不能在所有情況下都使用它們。 尤其是在那些可重用機(jī)會很小的地方。 在這種情況下,可以使用帶有分組斷言的私有方法。
你有什么意見?
資源資源
- 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測試使用斷言
總結(jié)
以上是生活随笔為你收集整理的mock测试使用断言_使用自定义断言丰富测试代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 世纪凤凰城备案价(风凰城备案价)
- 下一篇: 如何在Flutter(REST API)