freepascal / mockito

Automatically exported from code.google.com/p/mockito
0 stars 0 forks source link

Would like to be able to have a Serializable mock #110

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create a mock with extra interface of Serializable
2. Serialize the mock
3. Exception in thread "main" java.io.NotSerializableException: 
org.mockito.internal.creation.MethodInterceptorFilter

What is the expected output?  Object is serialized successfully. 

What do you see instead? NotSerializableException

What version of the product are you using? On what operating system? 1.8

Please provide any additional information below.

Original issue reported on code.google.com by wesandevie on 13 Aug 2009 at 4:11

GoogleCodeExporter commented 9 years ago
Hi,

Interesting feature - what is the main use case for serialized mocks? You're 
welcome
to provide a patch.

Original comment by szcze...@gmail.com on 17 Aug 2009 at 4:41

GoogleCodeExporter commented 9 years ago
Hey Szczepan, it is Wes (your co-worker :) ).  I want this for mocking an 
external 
dependency in a FitNesse test case that ultimately gets serialized by the web 
application.  It is something that may actually be a problem in the application 
i am 
trying to test because i am not sure this object should ever end up in the 
webflow 
(where it is being serialized) but it is to big of a change to the application 
for me 
to make now.

Original comment by wesandevie on 20 Aug 2009 at 6:49

GoogleCodeExporter commented 9 years ago
Hi Wes! :)

Will see what we can do

Original comment by szcze...@gmail.com on 20 Aug 2009 at 2:49

GoogleCodeExporter commented 9 years ago
I'm slowly plowing through. Unfortunately it involves some coding, not just 
making
all classes implement Serializable :)

Original comment by szcze...@gmail.com on 24 Aug 2009 at 7:37

GoogleCodeExporter commented 9 years ago
This would be a very useful feature for me. My use case is as follows:

I currently have a test environment set up where I create mocks of service 
interfaces
on test machine A, serialize them, and upload them to web server B in order to 
do
web-layer tests on an app that's in a known state.

Presently I use EasyMock to achieve this because its mocks are serializable. 
However,
our shop uses Mockito everywhere else for our mocking needs (plus I much prefer
Mockito's syntax) and so I would happily drop EasyMock in favour of Mockito if 
I could.

Original comment by brian.la...@gmail.com on 8 Oct 2009 at 3:50

GoogleCodeExporter commented 9 years ago
I started implementing it but I have no idea when I finish. It is quite hard 
because
I need to make many classes serializable and some of them contain jdk classes 
that
aren't serializable (like Method.class). It's going to take a while. Feel free 
to
contribute the patch.

Original comment by szcze...@gmail.com on 20 Oct 2009 at 7:37

GoogleCodeExporter commented 9 years ago
ok, i might have some time later this week or on the weekend.  i have the 
mockito code 
and i will look at it.  Is it possible to hold info on all object that are not 
serializable and make those object transient?  Should be possible with Method 
but I am 
not sure what other classes you may be holding that are like that.  

Original comment by wesandevie on 21 Oct 2009 at 1:06

GoogleCodeExporter commented 9 years ago
I would prefer to avoid transient fields. I think it's better if we figure out 
a way
of storing any mock data in objects that are serializable. This means we will 
have to
replace Method with our own Method that is serializable, etc. 

It's still not going to work 100% time. For example, what if someone stubs a 
mock
with a return value that isn't Serializable? We should make sure the exception 
is
meaningful. 

Also, cglib might introduce some some fields to the class we don't know about 
that
might not be serializable :)

Anyway it's well worth spiking. There is already a top-level test case that is 
yet
ignored somewhere in the test code (look for *Serializable*Test).

Cheers!

Original comment by szcze...@gmail.com on 21 Oct 2009 at 6:53

GoogleCodeExporter commented 9 years ago
ok, i will put some more thought into it.  i did not have time this weekend, 
needed 
some time off. 

Original comment by wesandevie on 26 Oct 2009 at 2:29

GoogleCodeExporter commented 9 years ago
hey, i started looking at this and i figured this was not implemented at all 
and you 
simple test is already serializing and us-serializing.  what have you done and 
what 
remains.  what is a failing test for this?

Original comment by wesandevie on 26 Oct 2009 at 4:16

GoogleCodeExporter commented 9 years ago
AFAIK, the test is yest ignored. If you enable this test it should fail. Don't
remember the test name but it surely has 'serial...' in the name :)

Original comment by szcze...@gmail.com on 26 Oct 2009 at 10:40

GoogleCodeExporter commented 9 years ago
i enabled it and it passed.  that was the weird thing.  i even created a then 
section 
to verify it could de-serialized back to an object and they were equal.  i 
added a 
couple more test that serialized and de-serialized with boolean and string and 
those 
passed as well. :)  i am going to add a test with a more complicated serialized 
object 
to the mocked object and also add a test for throwing a nice error when the 
mock 
contains a non-serializable object.  do you have some time to pair this week?

Original comment by wesandevie on 27 Oct 2009 at 2:25

GoogleCodeExporter commented 9 years ago
nevermind - it is the intellij guy using eclipse. :) they are failing but with 
all test 
ignored eclipse says the test is passed.  intellij tells you there are no test 
and 
turns it yellow.

Original comment by wesandevie on 27 Oct 2009 at 7:09

GoogleCodeExporter commented 9 years ago
i have a question:  it seems we check for equality on a mock with ==.  I am 
sure there 
is a good reason for this but after serialization/de-serialization (is 
de-serialization 
the correct word???) they are no longer == but could still be equal.  Why do we 
check 
==? (see org.mockito.internal.creation.MethodInterceptorFilter.intercept(...)

Original comment by wesandevie on 27 Oct 2009 at 9:46

GoogleCodeExporter commented 9 years ago
The implementation is going fairly well:  covered is mocked interface, concrete 
class, partial mock (stubbing), matchers, answers, stubbing callback.  

there are some issues i am worried about still.
1) any object that overrides writeObject and readObject, like ArrayList, to 
handle 
serialization will have an issue.  i.e. the internal state is not really 
initialized 
and if it expects those objects to never be null serialization will puke.

2) mock equality.  this is wrong after deserialization because mockito does ==. 
 not 
sure all the implications here.

Original comment by wesandevie on 29 Oct 2009 at 9:37

GoogleCodeExporter commented 9 years ago
> #1 

does it mean you cannot stub a method to return an ArrayList?

> #2

When mockito iterates through the stubbed methods it uses the
InvocationMethod.matches() to match methods. Therefore this may have impact on
stubbing. Potential problems:

Foo foo = mock(Foo.class);
when(foo.bar()).thenReturn("baz");
//serialize
//deserialize & use
foo = deserialize();
String what = foo.bar(); //In theory, foo is now different object and stubbed 
method
might not be found.

I guess we need to check it out. Are you ready to commit your code?

Original comment by szcze...@gmail.com on 29 Oct 2009 at 1:25

GoogleCodeExporter commented 9 years ago
> #1

no, it is only an issue when you are mocking an ArrayList.  return a real 
(non-mock) 
ArrayList is fine because a real ArrayList is Serializable.  But the 
Serialization 
object does not get initialized if you mock the ArrayList causing a null 
pointer when 
serializing the ArrayList.

Original comment by wesandevie on 29 Oct 2009 at 1:39

GoogleCodeExporter commented 9 years ago
i am ready to commit.  would you like to review it first?

Original comment by wesandevie on 29 Oct 2009 at 1:40

GoogleCodeExporter commented 9 years ago
No, I'll review it after the commit :) Don't break the build, though

Original comment by szcze...@gmail.com on 29 Oct 2009 at 1:43

GoogleCodeExporter commented 9 years ago
haha, ok. give me commit rights. is the default ant task enough to run or do i 
need to 
run any other tasks?

Original comment by wesandevie on 29 Oct 2009 at 1:47