mockery icon indicating copy to clipboard operation
mockery copied to clipboard

Satisfy unexported methods on interface in different package

Open lukestoward opened this issue 2 years ago • 1 comments

I recently encountered an issue when trying to use mockery to generate a mock for an interface in package x that contains an unexported method.

// x/x.go

package x

type Foo interface {
	Bar()
	baz()
}

Generating a mock for this interface using

mockery --with-expecter --exported --dir x --name Foo --output mocks  
// y/y.go

package y

func example(t x.Foo) {
	t.Bar()
}
// y/y_test.go

func Test_example(t *testing.T) {
	foo := mocks.NewFoo(t)
	example(foo) // <-- error "cannot use foo (variable of type *mocks.Foo) as x.Foo value in argument to example: *mocks.Foo does not implement x.Foo (missing method baz)"
}

This is a limitation of in how we define a type to satisfy the interface. According to this post, if the type embeds the target interface, it satisfies the compiler. For example:

// Code generated by mockery v2.14.0. DO NOT EDIT.

package mocks

import mock "github.com/stretchr/testify/mock"

// Foo is an autogenerated mock type for the Foo type
type Foo struct {
	x.Foo // <-- manually adding this fixes the issue.
	mock.Mock
}

Therefore, my question is, would it be possible to embed the original interface in the mock if the interface has unexported methods?

Mockery Version

v2.14.0.

Golang Version

go 1.18.3

Installation Method

  • [x] go install

lukestoward avatar Jul 01 '22 16:07 lukestoward

You can embed the original interface to ensure mocked struct implements it.But you can not override it with mocked function. Because it is not exported, the mthod of the same name in the mock file is not the same as that method in the interface

FLAGLORD avatar May 25 '23 06:05 FLAGLORD