title: How to create mockable code without shadowing usages (preferably with interfaces)
body: <p>I've designed my system, so a layer receives an interface for a lower layer. This seems to be the best practice way to create mockable code in golang. The higher level layer can accept any struct that implements the interface, so you can call the higher layer with a real lower layer or a mocked lower layer. The problem is that the lower layers usages are lost. Because of the abstraction, the compiler can't see where the lower layer is used. This visibility is especially important when refactoring, so the programmer can see everywhere a function is used--without relying on control-f. I've included a minimized version of the current architecture, if you were to copy the code into an ide, you could see the issue by attempting to find all usages of <code>Get()</code> &gt; <code>Repository</code> &gt; repository.go</p>
  <p>How can I make this pattern work, using interfaces, without shadowing the usages of lower layers?</p>
  <h1>Package - main</h1>
  <h2>File - main.go</h2>
  <pre><code>package main
  
  import (
      &quot;awesomeProject1/internal&quot;
      &quot;fmt&quot;
  )
  
  func main() {
      realRepo := &amp;internal.Repository{}
      realService := internal.Service{Repo: realRepo}
      fmt.Println(realService.FindById(1))
  }
  </code></pre>
  <h1>Package - Internal</h1>
  <h2>File - service.go</h2>
  <pre><code>package internal
  
  type Service struct {
      Repo IRepository
  }
  
  type IRepository interface {
      Get(id uint64) string
  }
  
  func (service *Service) FindById(id uint64) string {
      return service.Repo.Get(id)
  }
  </code></pre>
  <h2>File - repository.go</h2>
  <pre><code>package internal
  
  type Repository struct {
  }
  
  func (repo *Repository) Get(id uint64) string {
      return &quot;a real value from db&quot;
  }
  </code></pre>
  <h1>Package - tests</h1>
  <h2>File - service_test.go</h2>
  <pre><code>package tests
  
  import (
      &quot;awesomeProject1/internal&quot;
      &quot;fmt&quot;
      &quot;testing&quot;
  )
  
  func TestService(t *testing.T) {
      mockRepo := &amp;MockRepository{}
      realService := internal.Service{Repo: mockRepo}
      fmt.Println(realService.FindById(1))
  }
  </code></pre>
  <h2>File - mock_repository.go</h2>
  <pre><code>package tests
  
  type MockRepository struct {
  }
  
  func (repo *MockRepository) Get(id uint64) string {
      return &quot;a fake value for testing&quot;
  }
  </code></pre>