Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
roth_stephan_clean_c20_sustainable_software_development_patt.pdf
Скачиваний:
29
Добавлен:
27.03.2023
Размер:
7.26 Mб
Скачать

Chapter 8 Test-Driven Development

Done!

The interesting question is this: When do we know that we are done? When the piece of software that we have to implement is finished and all requirements are satisfied? When we can discontinue running through the TDD cycle? Do we really have to test all the numbers from 1 up to 3999 each by a unit test to know that we’re done?

The simple answer: If all requirements on our piece of code have been successfully implemented, and we do not find a new unit test that would lead to new production code, we are done!

And that is exactly the case with our TDD kata. We could still add many more assertions to the test method; the test would pass each time without the necessity to change the production code. This is the way TDD “speaks” to us: “Hey, my friend, you’re done!”

The result is shown in Listing 8-25.

Listing 8-25.  This Version Has Been Checked In at GitHub with the Commit Message “Done”

#include <gtest/gtest.h>

#include <string> #include <array>

int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();

}

struct ArabicToRomanMapping { unsigned int arabicNumber; std::string romanNumeral;

};

const std::string arabicToRomanMappings { ArabicToRomanMapping { 1000, "M" }, ArabicToRomanMapping { 900, "CM" }, ArabicToRomanMapping { 500, "D" }, ArabicToRomanMapping { 400, "CD" }, ArabicToRomanMapping { 100, "C" },

364

Chapter 8 Test-Driven Development

ArabicToRomanMapping {

90,

"XC"

},

ArabicToRomanMapping {

50,

"L"

},

ArabicToRomanMapping {

40,

"XL"

},

ArabicToRomanMapping {

10,

"X"

},

ArabicToRomanMapping {

9,

"IX"

},

ArabicToRomanMapping {

5,

"V"

},

ArabicToRomanMapping {

4,

"IV"

},

ArabicToRomanMapping {

1,

"I"

}

};

std::string convertArabicNumberToRomanNumeral(unsigned int arabicNumber) { std::string romanNumeral;

for (const auto& mapping : arabicToRomanMappings) { while (arabicNumber >= mapping.arabicNumber) {

romanNumeral += mapping.romanNumeral; arabicNumber -= mapping.arabicNumber;

}

}

return romanNumeral;

}

// Test code starts here...

class RomanNumeralAssert { public:

RomanNumeralAssert() = delete;

explicit RomanNumeralAssert(const unsigned int arabicNumber) : arabicNumberToConvert(arabicNumber) { }

void isConvertedToRomanNumeral(std::string_view expectedRomanNumeral) const {

ASSERT_EQ(expectedRomanNumeral, convertArabicNumberToRomanNumeral (arabicNumberToConvert));

}

private:

const unsigned int arabicNumberToConvert;

};

365

Chapter 8 Test-Driven Development

RomanNumeralAssert checkIf(const unsigned int arabicNumber) { return RomanNumeralAssert { arabicNumber };

}

TEST(ArabicToRomanNumeralsConverterTestCase, conversionOfArabicNumbersToRomanNumerals_Works) {

checkIf(1).isConvertedToRomanNumeral("I"); checkIf(2).isConvertedToRomanNumeral("II"); checkIf(3).isConvertedToRomanNumeral("III"); checkIf(4).isConvertedToRomanNumeral("IV"); checkIf(5).isConvertedToRomanNumeral("V"); checkIf(6).isConvertedToRomanNumeral("VI"); checkIf(9).isConvertedToRomanNumeral("IX"); checkIf(10).isConvertedToRomanNumeral("X"); checkIf(20).isConvertedToRomanNumeral("XX"); checkIf(30).isConvertedToRomanNumeral("XXX"); checkIf(33).isConvertedToRomanNumeral("XXXIII"); checkIf(37).isConvertedToRomanNumeral("XXXVII"); checkIf(50).isConvertedToRomanNumeral("L"); checkIf(99).isConvertedToRomanNumeral("XCIX"); checkIf(100).isConvertedToRomanNumeral("C"); checkIf(200).isConvertedToRomanNumeral("CC"); checkIf(300).isConvertedToRomanNumeral("CCC"); checkIf(499).isConvertedToRomanNumeral("CDXCIX"); checkIf(500).isConvertedToRomanNumeral("D"); checkIf(1000).isConvertedToRomanNumeral("M"); checkIf(2000).isConvertedToRomanNumeral("MM"); checkIf(2017).isConvertedToRomanNumeral("MMXVII"); checkIf(3000).isConvertedToRomanNumeral("MMM"); checkIf(3333).isConvertedToRomanNumeral("MMMCCCXXXIII"); checkIf(3999).isConvertedToRomanNumeral("MMMCMXCIX");

}

366