shutej / gomock

Automatically exported from code.google.com/p/gomock
Apache License 2.0
0 stars 0 forks source link

Not an issue,but a question:How to mock a interface and pass it by pointer? #10

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Scenario is : caller pass mock to---->Method_0(mock),but Method_0(..) didn't 
call mock's method,and passed mock to------> Method_1(mock) 
,finally,mock.ToVerify() gets called in Method_1().Because Method_0 will COPY 
mock then pass new copied mock to Method_1(),actual method call will happend in 
this copy not the original,but verification still binds on original mock.So it 
will fail.So question is How to mock a  interface and pass it by pointer?

   In my current use case,http.ResponseWriter must be mocked ,but I think question should be applied to other similar use cases.

//test
func TestXXX(t *testing.T) {
       mock:=......stuff to create mock......

       //action
       p.Method_0(mock)

       //verify
       mock.EXPECT().ToVerify()
}

//pakage p
package p

Method_0(mock http.ReponseWriter){
    //created copy and pass copy to Method_1
     Method_1(mock)
}

Method_1(mock http.ReponseWriter){
      //mock method gets called here
     mock.Write(...) 
}

Original issue reported on code.google.com by Alexande...@gmail.com on 5 Sep 2012 at 5:53

GoogleCodeExporter commented 9 years ago
Your question doesn't make sense. The mock you create is a concrete type of the 
form *T, and *T implements the mocked interface. You are not passing a copy of 
the object when you use it as an interface value.

Original comment by dsymo...@golang.org on 5 Sep 2012 at 7:45

GoogleCodeExporter commented 9 years ago
What do you mean?
I ran this command line to generate,and want to get a mock of 
http.ResponseWriter:
---------------------------------------------------------------
mockgen --source go/src/pkg/net/http/server.go -> 
/home/alex/IdeaProjects/AWS/src/activity/mock_server.go
---------------------------------------------------------------

Original comment by Alexande...@gmail.com on 5 Sep 2012 at 9:24

GoogleCodeExporter commented 9 years ago
Look in mock_server.go. There's a NewMockResponseWriter that returns
*MockResponseWriter, which satisfies the http.ResponseWriter
interface. You pass the *MockResponseWriter to the relevant
function/method.

Original comment by dsymo...@golang.org on 5 Sep 2012 at 1:02

GoogleCodeExporter commented 9 years ago
I tried it,got an error:
cannot use responseWriterMock (type *MockResponseWriter) as type 
*http.ResponseWriter in function argument:
*http.ResponseWriter is pointer to interface, not interface

Original comment by Alexande...@gmail.com on 11 Sep 2012 at 5:14

GoogleCodeExporter commented 9 years ago
Yeah? It's telling you what you're doing wrong: your code should be
taking an http.ResponseWriter, not a pointer to it.

Original comment by dsymo...@golang.org on 11 Sep 2012 at 5:16

GoogleCodeExporter commented 9 years ago
I come from java,so I can't make sure whether I have understood it 
correctly:during passing an interface,a copy will be made,and then all 
operations won't happened in the original but the copy,so verification will 
fail,right?:

func m_0(wr *http.ResponseWriter){
//here, a copy of wr will be passed into m_1,if change the signature of m_1 to
// m_1(wr http.ResponseWriter),all verification will fail,right?
     m_1(wr)
}

func m_1(wr *http.ResponseWriter){
    (*wr).Write(..)
}

Original comment by Alexande...@gmail.com on 11 Sep 2012 at 5:45

GoogleCodeExporter commented 9 years ago
I think you need to go learn about interfaces before trying to use
gomock. Perhaps start here:
http://golang.org/doc/effective_go.html#interfaces_and_types

Original comment by dsymo...@golang.org on 11 Sep 2012 at 5:48

GoogleCodeExporter commented 9 years ago
I still can't solve this problem,would you please give a more detailed 
explanation?I want to verify wr.Write(..) do get invoked as following?

func m_0(wr *http.ResponseWriter){
     m_1(wr)
}

func m_1(wr *http.ResponseWriter){
    (*wr).Write(..)
}

Original comment by Alexande...@gmail.com on 12 Sep 2012 at 5:52

GoogleCodeExporter commented 9 years ago
Like I said back in #5, you should not be using pointers to interfaces.

This isn't GoMock specific. Please take further questions to the golang-nuts 
mailing list.

Original comment by dsymo...@golang.org on 12 Sep 2012 at 5:55