Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interface mocking #3

Open
ZaynJarvis opened this issue Oct 9, 2022 · 9 comments
Open

interface mocking #3

ZaynJarvis opened this issue Oct 9, 2022 · 9 comments
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@ZaynJarvis
Copy link

ZaynJarvis commented Oct 9, 2022

Is your feature request related to a problem? Please describe.

A quick guide for interface mocking is needed

Describe the solution you'd like

type Fooer interface{
	Foo(string) string
}

type A struct{}

func (a A) Foo(in string) string { return in }

func UseFoo(f Fooer) string {
        // something
        return f.Foo("")
}

func TestMockXXX(t *testing.T) {
	PatchConvey("TestMockXXX", t, func() {
                Mock(Fooer.Foo).Return("c").Build() // something like this is needed

		So(UseFoo(A{}), ShouldEqual, "c") // assert `Fooer.Foo` is mocked
	})
}

Describe alternatives you've considered

func TestMockXXX(t *testing.T) {
	PatchConvey("TestMockXXX", t, func() {
                MockInterface(Fooer.Foo).Return("c").Build() // something like this is needed

		So(UseFoo(A{}), ShouldEqual, "c") // assert `Fooer.Foo` is mocked
	})
}

Additional context

  • for now GetNestedMethod seems to work, but not elegant.
  • I know I can do interface insertion, but this Mock func is just so good, I want to use it the same way.
@ycydsxy
Copy link
Collaborator

ycydsxy commented Oct 11, 2022

Mock(Fooer.Foo).Return("c").Build() means 'mock every implements of the Fooer interface', right?

@ycydsxy ycydsxy self-assigned this Oct 11, 2022
@ycydsxy ycydsxy added the enhancement New feature or request label Oct 11, 2022
@ZaynJarvis
Copy link
Author

yes that will be expected.

In case there are same interface in a structure for example

type A struct {
   X Fooer
   Y Fooer
}

Mock(A.X.Foo) may be a neat way.

@DNSun
Copy link

DNSun commented Nov 9, 2023

Is your feature request related to a problem? Please describe.

A quick guide for interface mocking is needed

Describe the solution you'd like

type Fooer interface{
	Foo(string) string
}

type A struct{}

func (a A) Foo(in string) string { return in }

func UseFoo(f Fooer) string {
        // something
        return f.Foo("")
}

func TestMockXXX(t *testing.T) {
	PatchConvey("TestMockXXX", t, func() {
                Mock(Fooer.Foo).Return("c").Build() // something like this is needed

		So(UseFoo(A{}), ShouldEqual, "c") // assert `Fooer.Foo` is mocked
	})
}

Describe alternatives you've considered

func TestMockXXX(t *testing.T) {
	PatchConvey("TestMockXXX", t, func() {
                MockInterface(Fooer.Foo).Return("c").Build() // something like this is needed

		So(UseFoo(A{}), ShouldEqual, "c") // assert `Fooer.Foo` is mocked
	})
}

Additional context

  • for now GetNestedMethod seems to work, but not elegant.
  • I know I can do interface insertion, but this Mock func is just so good, I want to use it the same way.

can't agree more! and how is the feature going? @ycydsxy

@foundVanting
Copy link

+1

1 similar comment
@stulzq
Copy link

stulzq commented Feb 29, 2024

+1

@zzraiyn1314
Copy link

+1

1 similar comment
@12345dotblue
Copy link

+1

@RicardoAGu
Copy link

RicardoAGu commented Sep 4, 2024

+1, we meet another problem related to interface mocking: If a public interface has a private struct to implement it, the method of the interface can not be mocked.

package packageA

type Fooer interface {
    Foo(string) string
}

type fooer struct {}

func (f *fooer) Foo(in string) string {
    return in
}

func GetFooer() Fooer {
    return &a{}
}

in another package:

package packageB
func TestFoo(t *testing.T) {
    PatchConvey("TestFoo", t, func(){
        // fooer is not an exported struct, can't mock like this
        // Mock((*packageA.fooer).Foo).Return("b").Mock() 
        out := packageA.GetFooer().Foo("a")
        So(out, shouldEqual, "b")   // test failed
    })
}

And if the method is mocked to a function, we can even not express the method's signature...
code like this is invalid:
Mock(GetMethod(GetFooer(), "Foo")).To(func (*packageA.fooer, string) string)

@Sychorius
Copy link
Collaborator

@RicardoAGu
Here is a way to mock with signature:

target := GetMethod(GetFooer(), "Foo")
hook :=  reflect.MakeFunc(target, ... ).Interface() // build hook with MakeFunc, use reflect.Value as params
Mock(target).To(hook)

If you don't need the method's signature, you can just simply remove it like this:
Mock(GetMethod(GetFooer(), "Foo")).To(func (string) string {xxx} )

@Sychorius Sychorius added the help wanted Extra attention is needed label Sep 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

9 participants