petergtz / pegomock

Pegomock is a powerful, yet simple mocking framework for the Go programming language
Apache License 2.0
254 stars 28 forks source link

[]ReturnValue not able to deal with channel directions #84

Closed emman27 closed 5 years ago

emman27 commented 5 years ago

Code example (modified from my own code):

type s s{}

type iface interface{
  f() (<- chan s, <- chan error)
}

func Test_i(t *testing.T) {
  i := NewMockiface()
  When(i.f()).Then(func([] Param) ReturnValues {
    c := make(chan s)
    e := make(chan error)
    go func() {
      c <- s{}
      close(c)
      close(e)
    }()
    return []ReturnValue{s, e}
  })
}

Generates the following error

interface conversion: pegomock.ReturnValue is chan s, not <-chan s

Seems it can't deal with the direction of the channels. Any possibility that this can be cleaned up?

emman27 commented 5 years ago

(Fixing in test code can be done via explicit conversion, but it looks awful)

func Test_i(t *testing.T) {
  i := NewMockiface()
  When(i.f()).Then(func([] Param) ReturnValues {
    c := make(chan s)
    e := make(chan error)
    go func() {
      c <- s{}
      close(c)
      close(e)
    }()
    return []ReturnValue{(<-chan s)(s), (<-chan error)(e)}
  })
}
petergtz commented 5 years ago

Hi @emman27 and thanks for reporting this. I will have a look at this as soon as possible (currently travelling with no proper access to a computer). Will get back to you.

petergtz commented 5 years ago

Hi @emman27, had a closer look at this now. Unfortunately, I don't think there is a way to clean this up. Your explicit conversions are the way to go. I know this is not very satisfying, but in general using the callback functions in pegomock is not very satisfying, because in pegomock's implementation I have to use a lot of reflection to deal with the interafce{}s. The only solution would be generics, which we don't have (yet).

petergtz commented 5 years ago

@emman27 thinking about it a little more, let me check if we can have a special case for this in the implementation. Maybe something along the lines of when the target type is a channel with direction, a channel with no direction as source type is also fine. Will get back to you.

petergtz commented 5 years ago

@emman27 Could you please try the develop branch and see if that fixes your problem? If so, I'll merge it into mainline and make a new release. Thank you.

emman27 commented 5 years ago

Thanks @petergtz

Just wondering what I need to do to make this work - from what I understand - the changes are on the mock generation side? So I should reinstall the CLI tool and regenerate my mocks, followed by re-running my test cases? Doesn't seem to be working for me, unfortunately.

(Here's my step-through process, in case I've missed something)

go get github.com/petergtz/pegomock
cd ~/go/src/github.com/petergtz/pegomock
git checkout develop
git fetch && git pull
go install github.com/petergtz/pegomock
cd ~/myproj (I'm using go modules)
pegomock generate --package myproj --use-experimental-model-gen -o interface.generated_test.go ./interface.go
go test ./ (I have some test that uses []ReturnValue{})
petergtz commented 5 years ago

@emman27 The line

go install github.com/petergtz/pegomock

should be

go install github.com/petergtz/pegomock/pegomock

because the binary sits in that sub-directory.

With that change I think it should work for your case. However, I just noticed that another case is not working anymore now. Will provide a fix soon.

petergtz commented 5 years ago

@emman27 Just provided a fix that should make channels work in all cases. Please try with latest from develop. Make sure to install the pegomock binary as described in https://github.com/petergtz/pegomock/issues/84#issuecomment-491740230.

emman27 commented 5 years ago

@petergtz works great for me! Thanks!

petergtz commented 5 years ago

Released on master as v2.3.0. Closing. Please re-open if there is anything missing. Thanks again.