Last active
March 7, 2019 17:19
-
-
Save timruffles/82fdc49f87026198f902febb7d75d16a to your computer and use it in GitHub Desktop.
Go - cost of change for methods in application code. App code has many types that work together, requiring mocking.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Let's define a type with a method that needs a fair few arguments | |
type Thing struct {} | |
func (c *Thing) Verb(a A,b B,c C,d D) {} | |
// We have things that depend on Thing and we want to test them, so to mock it we'll need to | |
// define an interface and generate a mock | |
type Thinger interface { | |
Verb(a A,b B,c C,d D) | |
} | |
type MockThing struct{} | |
func (c *MockThing) Verb(a A,b B,c C,d D) {} | |
// Okay, now the cost of changing Method's arguments is: | |
// 1. update interface | |
// 2. regenerate mock | |
// in addition to updating callers to those methods: concrete and in test | |
// We could dodge this by rolling up the arguments into a value object, however, this is now | |
// really unsafe as we can't make the struct require all args | |
type VerbArgs struct { A A, B... } | |
func (c *Thing) VerbV2(args VerbArgs) {} | |
// Whoops, now C and D are zero-values. Havok may ensure | |
c.VerbV2(VerbArgs{A,B}) | |
// If we make a factory for VerbArgs we have safety and a lower cost of change: changing the args doesn't require | |
// a change to the Verb method, so the Thinger interface and MockThing don't need updating. | |
func newVerbArgs(a A,B...) VerbArgs {} | |
// However: if we don't move `VerbArgs` into its own package, and conceal the struct type, people can | |
// still forget and use `VerbArgs` directly, which gives us the zero-value problem again. Making a interface | |
// type for it with getters would be safe but it's a heap of code. This could be tooled though, so seems somewhat | |
// tractable. | |
// A likely non-answer: "make it take fewer arguments". Okay, then we need to define value-objects which | |
// needs to conceal its structure with a separate package + getters to avoid the zero-value problem mentioned above. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment