A common annoyance when doing certain types of API coding is Go’s lack of structural data typing. In my personal experience, this can result in having to write a massive amount of boilerplate to convert between concrete types that are broadly the same, but are either slightly different (say, a DB type that has a few extra fields than a domain type which in turn has a few extra fields than an API return type) or are just in different packages.
Interface intersections are a quite handy feature in Typescript. For those without Typescript experience, they allow you to easily define a new type that is the intersection of two different types. To pull an example from the language guide, say you have an interface for objects with a colour and an interface for circles, like so:
interface Colourful { colour: string; } interface Circle { radius: number; } Now a lot of your logic may deal with only a Colourful object or only a Circle, but sometimes you want to write something that operates only on a circle that is also colourful.
What is a mock “Mock” is one of those words that means subtly different things to different people, so, to be specific, in this post I am using the following definition: a mock is a test double that stands in for a real component by satisfying its API and enforces assertions on how that API gets called during a test. The mocks that mockery generates would be Go examples.
Every mock writes a contract Tests codify promises about functionality into executable logic that can verify that those promises are kept, effectively making them contracts with built-in enforcement.
Almost every engineer writes example-based tests. You pick some inputs, determine what the output should be, and then write some sort of test harness that will provide those inputs to the code under test and check that the output matches your expectations. It’s the first kind of testing most of us learn and it makes up the bulk of nearly every test suite I’ve ever worked in. It’s so familiar that it has become more or less invisible, in many cases when we talk about tests, we are implicitly assuming that we’re talking about example-based tests, and rarely do we actually stop to reflect on what it is (and isn’t) doing for us as a testing methodology.
I’m planning on starting a series of blog posts discussing different testing methodologies, but before I do that, I need to get a rant off my chest, and it pertains to a topic that is discussed ad nauseum whenever you bring up “testing methodologies.” A topic that is, in my mind, neither very interesting nor very valuable and gets in the way of more useful discussions.
The pointless conversation we keep having Have you ever been in a meeting and someone starts discussing the relative importance of unit, integration, etc.
Exceptions suck Error handling and reporting is something that has always bothered me. If you use a checked exception model, your code rapidly becomes very verbose and your interfaces very brittle, which can often push programmers toward very lazy exception handling. On the other hand, if you use an unchecked exception model, you are completely dependent on the developers of the code you call documenting every exception that can be thrown so you know what errors can occur (unless you want to go spelunking through their code anyway).