Notes

Part 1: Just the basics

1By the way, TDD is not only about unit tests, which we will get to eventually.

2I don’t know who said it first, I searched the web and found it in few places where none of the writers gave credit to anyone else for it, so I decided just to mention that I’m not the one that coined this phrase.

3besides, this book is open source, so if you don’t like the terminology, you are free to create a fork and change it to your liking!

4I know copy-pasting code is considered harmful and we shouldn’t be doing that. When writing unit-level Statements, I make some exceptions to that rule. This will be explained in further parts.

5K. Pugh, Prefactoring, O’Reilly Media, 2005

6There are also some arguments against using the word “should”, e.g. by Kevlin Henney (see https://www.infoq.com/presentations/testing-communication).

7This approach of picking a single value out of several ones using Any.From() does not always work well with enums. Sometimes a parameterized test (a “theory” in XUnit.NET terminology) is better. This topic will be discussed in one of the coming chapters.

8Look for details in chapter 2.

9Some claim there are other keywords, like But and Or. However, we won’t need to resort to them so I decided to ignore them in this description.

10Seb Rose wrote a blog post where he suggests against the //GIVEN //WHEN //THEN comments and states that he only uses empty lines to separate the three sections, see http://claysnow.co.uk/unit-tests-are-your-specification/

11Some disagree, however, with writing Statements on the class level - see http://blog.cleancoder.com/uncle-bob/2017/03/03/TDD-Harms-Architecture.html or https://vimeo.com/68375232

12Clean Code series, episode 19 (https://cleancoders.com/episode/clean-code-episode-19-p1/show), Robert C. Martin, 2013

13One of such articles can be found at https://martinfowler.com/articles/mocksArentStubs.html

14A “false positive” is a test that should be failing but is passing.

15For the biggest collection of such techniques, or more precisely, patterns, see XUnit Test Patterns by Gerard Meszaros.

16see e.g. chapter 4.3 of ISQTB Foundation Level Syllabus at http://www.istqb.org/downloads/send/2-foundation-level-documents/3-foundation-level-syllabus-2011.html4

17https://en.wikipedia.org/wiki/Tetraphobia

18https://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests/153565#153565

Part 2: Object-Oriented World

1I am simplifying the discussion on purpose, leaving out e.g. functional languages and assuming that “pre-object-oriented” means procedural or structural. While this is not true in general, this is how the reality looked like for many of us. If you are good at functional programming, you already understand the benefits of composability.

2More on context-independence and what these “special places” are, in the next chapters.

3I got this saying from Amir Kolsky and Scott Bain

4Sure, we could pass a null but then we are the ones asking for trouble.

5If you never used collections before and you are not a copy-editor, then you are probably reading the wrong book :-)

6Kent Beck, Implementation Patterns

7This pattern has a name and the name is… Null Object (surprise!). You can read more on this pattern at http://www.cs.oberlin.edu/~jwalker/nullObjPattern/ and http://www.cs.oberlin.edu/~jwalker/refs/woolf.ps (a little older document)

8For details, check Dependency Injection in .NET by Mark Seemann.

9

  1. Shalloway et al., Essential Skills For The Agile Developer.

10although it does need to change when the rule “first validate, then apply to sessions” changes

11Note that this is an application of a Gang of Four guideline: “encapsulate what varies”.

12The two versions of the API would probably be hosted on different URLs or different ports. In a real-world scenario, these different values would probably need to be passed as constructor parameters as well.

13There are simpler ways, yet none is as flexible as using factories.

14

  1. Shalloway et al., Essential Skills For The Agile Developer.

15http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

16Scott Bain, Emergent Design

17This topic is outside the scope of the book, but you can take a look at: M. Fowler, Domain-Specific Languages, Addison-Wesley 2010

18This is sometimes called Feature Envy. It means that a class is more interested in other class’ data than its own.

19We can even further refactor this into a state machine using a Gang of Four State pattern. There would be two states in such a state machine: started and expired.

20This principle can be applied to methods as well, but we are not going to cover this part, because it is not directly tied to the notion of composability and this is not a design book ;-).

21http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod.

22https://stackoverflow.fogbugz.com/default.asp?W29030

23Provided we are not using a measure such as story points.

24Note that I’m writing about responsibility in terms of the single responsibility principle. In Responsibility-Driven Design, responsibility means something different. See Rebecca Wirfs-Brock’s clarification.

25Note that I am talking about responsibilities the way SRP talks about them, not the way they are understood by e.g. Responsibility-Driven Design. Thus, I am talking about the responsibilities of a class, not the responsibilities of its API.

26SMTP stands for Simple Mail Transfer Protocol and is a standard protocol for sending and receiving e-mail. You can read more on Wikipedia.

27M. Fowler, Domain-Specific Languages, Addison-Wesley 2010.

28M. Fowler, Domain-Specific Languages, Addison-Wesley 2010.

29A reader noted that the ideas in this section are remarkably similar to the notion of Bounded Contexts in a book: E. Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software, Prentice Hall 2003.

30M. Fowler, Domain-Specific Languages, Addison-Wesley 2010.

31In some languages, there is a third way: Java lets us use static imports which are part of C# as well starting with version 6.0. C++ has always supported bare functions, so it’s not a topic there.

32S. Freeman, N. Pryce, Growing Object-Oriented Software Guided by Tests, Addison-Wesley Professional, 2009

33All engineering decisions are trade-offs anyway, so I should say “some of them make better trade-offs in our context, and some make worse”.

34and, for C#, overriding equality operators (== and !=) is probably a good idea as well, not to mention GetHashCode() (See https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/equality-operators)

35In reality, this is only partially true. For example, we will have to override ToString() somewhere anyway to ensure interoperability with 3rd party libraries that don’t know about our ProductName type, but will accept string arguments. Also, one can always use reflection to get private data. I hope you get the point though :-).

36https://stackoverflow.com/questions/2734914/whats-the-difference-between-iequatable-and-just-overriding-object-equals

37By the way, the code contains a call to IsNullOrEmpty(). There are several valid arguments against using this method, e.g. by Mark Seemann (http://blog.ploeh.dk/2014/11/18/the-isnullorwhitespace-trap/), but in this case, I put it in to make the code shorter as the validation logic itself is not that important at the moment.

38This is true for languages like Java, C# or C++. There are other languages (like Ruby), with different rules regarding object construction. Still, the original argument - that the naming of methods responsible for object creation is constrained - holds.

39

  1. Shalloway et al., Essential Skills For The Agile Developer.

40This is sometimes called “aliasing bug”: https://martinfowler.com/bliki/AliasingBug.html

41Unless Java optimizes it somehow, e.g. by using the copy-on-write approach.

42This is one of the reasons why functional languages, where data is immutable by default, gain a lot of attention in domains where doing many things in parallel is necessary.

43this example uses a library called Atma Filesystem: https://www.nuget.org/packages/AtmaFilesystem/

44This example is loosely based on Kent Beck’s book Test-Driven Development By Example.

45I could use extension methods to make the example even more idiomatic, e.g. to be able to write 5.Dollars(), but I don’t want to go to far in the land of idioms specific to any language, because my goal is an audience wider than just C# programmers.

46I am aware that this example looks a bit naive - after all, adding money in several currencies would imply they need to be converted to a single currency and the exchange rates would then apply, which could make us lose money. Kent Beck acknowledged and solved this problem in his book Test-Driven Development By Example - be sure to take a look at his solution if you’re interested.

47This is what Java did. I don’t declare that Java designers made a bad decision - a single Path class is probably much more versatile. The only thing I’m saying is that this design is not optimal for our particular scenario.

48for reference, please take a look at https://www.nuget.org/packages/AtmaFilesystem/

49frankly, as in the case of money, the vision of paths I described here is a bit naive. Still, this naive view may be all we need in our particular case.

50C# has structs, which can sometimes come in handy when implementing values, even though they have some constraints (see https://stackoverflow.com/questions/333829/why-cant-i-define-a-default-constructor-for-a-struct-in-net). Also, since more recent releases, C# has records which can be sometimes used to cut some of the boilerplate.

Part 3: TDD in Object-Oriented World

1more on this in further chapters.

2that’s why typically I don’t specify that something should rethrow an exception – I do it this time because otherwise, it would not let me specify how DataDispatch uses a Channel.

3of course, the idiomatic way to do it in C# would be to use the IDisposable interface and a using block (or IAsyncDisposable and await using in the case of async calls).

4Patterns of enterprise application architecture, M. Fowler.

5https://www.pmi.org/disciplined-agile/the-design-patterns-repository/the-facade-pattern

6https://www.pmi.org/disciplined-agile/the-design-patterns-repository/the-command-pattern

7Refactoring to Patterns, Joshua Kerievsky

8https://www.pmi.org/disciplined-agile/the-design-patterns-repository/the-decorator-pattern

9though both C# and Java in their current versions allow putting logic in interfaces. Still, due to convention and some constraints, interfaces in those languages are still considered as beings without implementation.

10http://www.sustainabletdd.com/2012/02/testing-best-practices-test-categories.html

11Steve Freeman, Nat Pryce, Growing Object Oriented Software Guided By Tests

12Patterns of Enterprise Application Architecture, Martin Fowler

13https://martinfowler.com/eaaCatalog/mapper.html

14http://www.natpryce.com/articles/000714.html

15https://blog.ploeh.dk/2017/08/15/test-data-builders-in-c/

16https://wiki.c2.com/?CollectingParameter