How to mock a method call of a struct in the test case

You’re right, my bad. I wrote this code too quickly and did not test it. For the second option, you need an interface. Let me start from the beginning.

Your library package needs no change. Well, one change: Use a capital P for method Perform to make it visible outside the package.
For testing purposes, I also added a return parameter.

perf/perf.go:

package perf

type A struct{}

func (a *A) Perform(s string) int {
	return len(s)
}

In main, you define an interface:

main.go:

package main

import (
	"fmt"
	"perf" // adjust this path depending on where you put perf
)

type Performer interface {
	Perform(string) int
}

func invoke(url string, p Performer) int {
	return p.Perform(url)
}

func main() {
	a := perf.A{}
	url := "https://appliedgo.net" // shameless plug :-)
	fmt.Println(invoke(url, &a))  // We need to pass a pointer here because Perform() has a pointer receiver
}

And in your test file, create and use mockA. Invoke() will accept it as it implements the Performer interface:

invoke_test.go:

package main

import "testing"

type mockA struct{}

func (m *mockA) Perform(s string) int {
	return len(s)
}

func Test_invoke(t *testing.T) {
	m := mockA{}
	url := "https://appliedgo.net"
	want := 21
	if got := invoke(url, &m); got != want {
		t.Errorf("invoke() = %v, want %v", got, want)
	}
}

(This time I tested the code :slight_smile: )

2 Likes