In a Golang project that I have worked on so far, it’s pretty common to see developers creating concrete struct directly to implement service, which is reusable from another module, without using an interface. If the struct has a dependency on another component, the dependency is also instantiated inside the struct’s method itself

Let’s say your code needs to call a wrapper to an external service. And then the external service wrapper is created like this

type ExternalService struct {
config *Config
}

func New() *ExternalService {
return &ExternalService{
config: getConfig(),
}
}

func (externalService *ExternalService) CallService error {
// imagine this is the method to call the external service
}

No problem, until we need to create a unit test for our calling code who calls the external service. Let’s say that your organization policy requires a code to pass an 80% coverage before the code is being merged.

And because the external service is down, all the call to CallService throws an error and failed. Since this is failed, the coverage is less than 80% and the code can’t be merged, even though there’s no compile error.

A common practice is to mock this service with a mock object. But then this ExternalService is not mockable, since it does not implement any interface, and the client code instantiating it directly.

So how do we modify this ExternalService struct so we can mock it for our unit test?

To be continued….