You can subscribe to this list here.
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(5) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(17) |
Feb
(7) |
Mar
(2) |
Apr
|
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
(4) |
Oct
|
Nov
(6) |
Dec
(4) |
2007 |
Jan
(1) |
Feb
|
Mar
(10) |
Apr
(3) |
May
(4) |
Jun
(7) |
Jul
|
Aug
(5) |
Sep
|
Oct
|
Nov
|
Dec
(3) |
2008 |
Jan
|
Feb
|
Mar
(1) |
Apr
(3) |
May
(8) |
Jun
(7) |
Jul
(12) |
Aug
(3) |
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: James C. <jam...@gm...> - 2006-09-21 13:02:01
|
Hi, I was curious if there was a way to create mocks that don't have any expectations. For example, sometimes I want to fake out a BufferedReader and don't care at all how many times it's called, but rather only care that it returns, say, 5 different strings and then finally null when called more than 6 times. If you have any ideas, please let me know. Thanks, James |
From: Daniel B. <dan...@gm...> - 2006-09-19 14:27:07
|
Hello James! I wanted to give you a quick reply, hence I haven't tested your code. This problem resembles problems we've had when mocking/intercepting objects in Swing. Swing hangs on to references to mocked objects, and sometimes a sleeping thread kicks in and calls the mocks way after the test has finished. The solution in rmock should be: Disable all mocks after the test is finished to avoid these kinds of exceptions. The workarounds: Ignore the message or Try to detach all mocks given to Swing wherever possible. I hope it helped a little! Cheers Daniel On 9/19/06, James Carr <jam...@gm...> wrote: > Hi all, > > I am trying to mock some components out to test an ActionListener and > I have ran across some odd issues. The test passes fine and I see > green, but I also get the following exception: > > com.agical.rmock.core.hub.ReferenceOutOfScopeException: No reference > currently in scope for public abstract boolean > com.agical.rmock.core.expectation.ExpectationsState.isInVerifyState() > at com.agical.rmock.core.hub.ProxySetMethodConnectionStrategy$ConsumableInvocationHandler.invoke(ProxySetMethodConnectionStrategy.java:29) > at $Proxy2.isInVerifyState(Unknown Source) > at com.agical.rmock.extension.cglib.BaseInvocationHandler.sendInvocationListenerEvent(BaseInvocationHandler.java:37) > at com.agical.rmock.extension.cglib.ObjectMockInvocationHandler.intercept(ObjectMockInvocationHandler.java:67) > at $javax.swing.JFileChooser$$EnhancerByCGLIB$$31b4f017.getFileSystemView(<generated>) > at javax.swing.plaf.basic.BasicDirectoryModel$LoadFilesThread.run(BasicDirectoryModel.java:192) > > Here's my test case: > > public void testTextFieldIsUpdatedOnFileSelection() { > File mockFile = (File)mock(File.class, new > Class[]{String.class}, new String[]{"foo"}, "mockfile"); > mockFile.getAbsolutePath(); modify().returnValue("C:/config.txt"); > > JFileChooser chooser = (JFileChooser) mock(JFileChooser.class); > chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); > chooser.showOpenDialog(null); > modify().returnValue(JFileChooser.APPROVE_OPTION); > chooser.getSelectedFile(); modify().returnValue(mockFile); > startVerification(); > > FileDialogListener listener = new FileDialogListener(); > listener.setChooser(chooser); > JTextField field = new JTextField(); > listener.setTargetField(field); > > ActionEvent mouseClick = new ActionEvent(new JButton("foo"), 1, "DoFoo!"); > > listener.actionPerformed(mouseClick); > assertNotNull("Field should have been set!", field.getText()); > } > > And my class: > > package listeners; > > import java.awt.event.ActionEvent; > import java.awt.event.ActionListener; > > import javax.swing.JFileChooser; > import javax.swing.JTextField; > > public class FileDialogListener implements ActionListener{ > > private JTextField _targetField; > private JFileChooser chooser; > > public void setChooser(JFileChooser chooser){ > this.chooser = chooser; > } > > public void actionPerformed(ActionEvent e) { > getFileChooser().setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); > int result = getFileChooser().showOpenDialog(null); > if(result == JFileChooser.APPROVE_OPTION){ > _targetField.setText(getFileChooser().getSelectedFile().getAbsolutePath()); > } > } > > public void setTargetField(JTextField field) { > _targetField = field; > > } > > public JFileChooser getFileChooser() { > if(chooser != null){ > return chooser; > } > return chooser = new JFileChooser(); > } > > > > } > > Any idea what is causing this? > > Thanks, > james > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Rmock-users mailing list > Rmo...@li... > https://lists.sourceforge.net/lists/listinfo/rmock-users > -- __________________________ Dan...@Gm... |
From: James C. <jam...@gm...> - 2006-09-19 12:47:42
|
Hi all, I am trying to mock some components out to test an ActionListener and I have ran across some odd issues. The test passes fine and I see green, but I also get the following exception: com.agical.rmock.core.hub.ReferenceOutOfScopeException: No reference currently in scope for public abstract boolean com.agical.rmock.core.expectation.ExpectationsState.isInVerifyState() at com.agical.rmock.core.hub.ProxySetMethodConnectionStrategy$ConsumableInvocationHandler.invoke(ProxySetMethodConnectionStrategy.java:29) at $Proxy2.isInVerifyState(Unknown Source) at com.agical.rmock.extension.cglib.BaseInvocationHandler.sendInvocationListenerEvent(BaseInvocationHandler.java:37) at com.agical.rmock.extension.cglib.ObjectMockInvocationHandler.intercept(ObjectMockInvocationHandler.java:67) at $javax.swing.JFileChooser$$EnhancerByCGLIB$$31b4f017.getFileSystemView(<generated>) at javax.swing.plaf.basic.BasicDirectoryModel$LoadFilesThread.run(BasicDirectoryModel.java:192) Here's my test case: public void testTextFieldIsUpdatedOnFileSelection() { File mockFile = (File)mock(File.class, new Class[]{String.class}, new String[]{"foo"}, "mockfile"); mockFile.getAbsolutePath(); modify().returnValue("C:/config.txt"); JFileChooser chooser = (JFileChooser) mock(JFileChooser.class); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.showOpenDialog(null); modify().returnValue(JFileChooser.APPROVE_OPTION); chooser.getSelectedFile(); modify().returnValue(mockFile); startVerification(); FileDialogListener listener = new FileDialogListener(); listener.setChooser(chooser); JTextField field = new JTextField(); listener.setTargetField(field); ActionEvent mouseClick = new ActionEvent(new JButton("foo"), 1, "DoFoo!"); listener.actionPerformed(mouseClick); assertNotNull("Field should have been set!", field.getText()); } And my class: package listeners; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFileChooser; import javax.swing.JTextField; public class FileDialogListener implements ActionListener{ private JTextField _targetField; private JFileChooser chooser; public void setChooser(JFileChooser chooser){ this.chooser = chooser; } public void actionPerformed(ActionEvent e) { getFileChooser().setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); int result = getFileChooser().showOpenDialog(null); if(result == JFileChooser.APPROVE_OPTION){ _targetField.setText(getFileChooser().getSelectedFile().getAbsolutePath()); } } public void setTargetField(JTextField field) { _targetField = field; } public JFileChooser getFileChooser() { if(chooser != null){ return chooser; } return chooser = new JFileChooser(); } } Any idea what is causing this? Thanks, james |
From: Joakim O. <joa...@ag...> - 2006-05-08 19:12:22
|
Hi Paul, Nice to hear from you again! The paper is an interesting read, comparing side by side with that simple example jMock does look the most apealing and readable IMO. Having working with it I know that I like to use it less than I like to read the code :) Have you tried using the assertThat(value, expression) way of asserting? I think it is very readable and I really like the flexibility it gives. I would have liked to see that feature in the paper but it is ultimately a matter of taste, I guess. About TDDoc with some luck we have something simple by the end of this week, we are working hard to finish it since we will be demonstrating it on XP2006 in a poster/demonstration session. We intend to release the final 2.0.0 version before XP2006 aswell (we don't want to release it until we are sure that it supports everything we need for TDDoc). We have rewritten parts of it several times to get it right and I finally think we nailed it. I currently have some problems with the source-parser before I can commit what I have on my computer. If you're interested in more details about where we are and how things work I can spend some more time to explain it on the list. We also have some rMock goodies to release soon. Quite a lot of refactorings have been going on. Mainly internals but we have also managed to squeeze in a few solutions/features to problems posted on this list like a defaults section and extend and overridSection (this functionality fills the gap of stubs). |
From: Paul K. <ki...@as...> - 2006-05-08 15:46:39
|
I put together a JMock, RMock, EasyMock, Groovy Mock comparison at: http://www.asert.com.au/pubs/Mocking/MockTest.pdf It's not much more than a bare example at the moment but I certainly found it to be a useful activity. I was interested to know whether you think tddoc is advanced along enough so that I could try to incorporate its capabilities into the RMock comparison. Cheers, Paul. |
From: Joakim O. <joa...@gm...> - 2006-03-28 07:39:27
|
We released rmock 2.0.0-rc-6 the other day. Notes: We've gotten rMock added to the Maven repositories! We've also made some bugfixes to dynamic suites as well as added some more methods to the multiplicity factory. We are currently working on: * The TDDoc extension. * Refactoring the test workflow to support customized tests. Changes: * Fixed bug 1431452: Dynamic suites got confused when the project path contained spaces. This was as far as we could tell a bug in JDK 1.4.2 when translating between URL and File, but this problem should now be worked-around in all places in the code by replacing %20 with space. * Fixed bug 1431455: When a dynamic suite tries to iterate through all classes it makes the jvm load the classes. When a class loaded is missing a dependency and ClassDefNotFoundError is thrown, and the suite fails. Now we catch and ignore that error. * rMock is now available in the Maven repositories! * Feature request 1439651: atMost(...) and atMostOnce() have been added to the MultiplicityFactory. |
From: Joakim O. <joa...@gm...> - 2006-03-15 08:58:36
|
Hi List! First our apologies that we have not been able to find the time to implement some of the requests on this list. We have not forgotten about it and we are currently refactoring rMock TestCase to prevent it from becoming more of a mess than it already is before adding more features to it. While I was doing just that I discovered a testing pattern that I thought I'd share on this list. It uses intercept in a slightly different way than was intended when it was added. In this case intercept is used to test abstract classes. First a quick description of intercept: Intercepting is almost like the inverse of mocking. When you mock rMock fails everything that has not been setup. With intercept (works only on concrete classes, ie not interfaces) rmock forwards everything to the intercepted class except for those methods that have been setup to be intercepted before startVerification. The reason we implemented it: testReaderIsClosedByTheUser() { Reader reader =3D (Reader)intercept(StringReader.class, new Object[]{"The String to be read"}, "reader"); reader.close(); modify().forward(); startVerification(); readerUser.useReader(reader); } The above testcase passes a StringReader to the readerUser, the difference from passing just a StringReader is that the above will fail if the readerUser does not close the reader. More details are available here: http://rmock.sourceforge.net/gettingstarted.html http://rmock.sourceforge.net/xref-test/com/agical/rmock/usage/stubbingobjec= ts/TestInterceptingObjects.html Ok now to the testpattern: While refactoring RMockTestCase we decided to have a baseclass allowing any strategy to be run when the test is run. To be able to test that the Class behaves as it should (in this case get a strategy based on the testName and run it) intercept comes in extremely handy: package com.agical.rmock.extension.junit; import com.agical.rmock.core.exception.RMockInternalError; import com.agical.rmock.core.strategy.TestStep; public class TestAbstractStrategyTestCase extends RMockTestCase { =09private AbstractStrategyTestCase abstractStrategyTestCase; =09protected void setUp() throws Exception { =09=09super.setUp(); // // Intercept subclasses the intercepted class, so abstract classes can be tested using // intercept without subclassing them. // =09=09abstractStrategyTestCase =3D (AbstractStrategyTestCase) intercept(AbstractStrategyTestCase.class, new Object[]{"test"}, "abstractStrategyTestCase"); =09=09 =09} =09 =09public void testTestRunsStrategy() throws Throwable { =09 // since we passed "test" to the constructor we expect "test" to be passed to the createStrategyMethod =09 TestStep strategy =3D abstractStrategyTestCase.createStrategy= ("test"); // a mock is automatically created for us and we expect rMock to run it. =09=09strategy.run(); =09=09 =09=09startVerification(); =09=09 // now run the test =09=09abstractStrategyTestCase.runBare(); =09} =09 =09public void testTestNoStrategy() throws Throwable { =09=09 // using the same class as above but chaning its behaviour without // adding complex parameters that are used only for testing= . // In this case we tell the implementStrategyMethod to return null. abstractStrategyTestCase.createStrategy("test"); =09=09modify().returnValue(null); =09=09 =09=09startVerification(); =09=09 // This is a quite new feature in rMock, here we expect an exception to be thrown as a result of running some code after this row. =09=09expectThatExceptionThrown(is.instanceOf(RMockInternalError.class)); =09=09abstractStrategyTestCase.runBare(); =09} } The code that passes this test looks like this: public abstract class AbstractStrategyTestCase extends TestCase { =09public AbstractStrategyTestCase(String name) { =09=09super(name); =09} =09 =09protected abstract TestStep createStrategy(String test); =09 =09public void runBare() throws Throwable { =09=09TestStep step =3D createStrategy(getName()); =09=09if (step =3D=3D null) { =09=09=09throw new RMockInternalError("The createStrategy(String) returned = null!"); =09=09} =09=09step.run(); =09} } The magic that is going on here is that, since interception uses subclassing to work, all invocations from _any_ class _including_ the intercepted class itself is intercepted. Pretty neat if you ask me :) Now a familiar example to stress the point, our BasicJUnitStrategyTestCase: package com.agical.rmock.extension.junit; public class TestBasicJUnitStrategyTestCase extends RMockTestCase { =09private BasicJUnitStrategyTestCaseExample testCase; =09protected void setUp() throws Exception { =09=09super.setUp(); =09=09testCase =3D (BasicJUnitStrategyTestCaseExample) intercept(BasicJUnitStrategyTestCaseExample.class, new Object[]{"testOne"}, "testCase"); =09} =09 =09public void testSetupTestMethodTearDown() throws Throwable { =09=09beginSection(s.ordered("testExecution")); =09=09{ =09=09=09testCase.setUp(); =09=09=09testCase.testOne(); =09=09=09testCase.tearDown(); =09=09} =09=09endSection(); =09=09 =09=09startVerification(); =09=09 =09=09testCase.runBare(); =09} public void testSetupTestMethodThrowsExceptionTearDownStillRun() throws Throwable { =09=09beginSection(s.ordered("testExecution")); =09=09{ =09=09=09testCase.setUp(); =09=09=09testCase.testOne(); modify().throwException(new Exception); =09=09=09testCase.tearDown(); // tearDown should still be run =09=09} =09=09endSection(); =09=09 =09=09startVerification(); =09=09 =09=09testCase.runBare(); =09} public void testSetupThrowsExceptionTearDownStillRun() throws Throwable { =09=09beginSection(s.ordered("testExecution")); =09=09{ =09=09=09testCase.setUp(); modify().throwException(new Exception); // setup failed, the test is not run =09=09=09testCase.tearDown(); // tearDown should still be run =09=09} =09=09endSection(); =09=09 =09=09startVerification(); =09=09 =09=09testCase.runBare(); =09} } I hope this was interesting, I was happy that I found this possibility. Any feedback most welcome.It would also be interesting to know about any tricks _you_ are using with rMock if you would like to share them with the list. PS. One of the reasons that we are implementing strategies is that we want to be able to streamline the workflow to be more suitable for rMock and allow rMock users to implement their own patterns without rewriting runBare completely. In the case above the code: =09startVerification(); =09testCase.runBare(); could be in a separate method or TestStep object. That would leave only the essentials for each case in each testMethod. DS. /J |
From: Daniel B. <dan...@gm...> - 2006-02-19 12:17:08
|
Hello all! rMock is now available in the maven repositories! Maven 1: http://www.ibiblio.org/maven/com.agical.rmock/ Maven 2: http://www.ibiblio.org/maven2/com/agical/rmock/ Have fun! /Daniel On 2/10/06, Tim Blommerde <t.b...@qu...> wrote: > Hello Daniel, > > Thanks for replying so quickly and of course for the help you offered. Th= e > project I referred to will probably start around the beginning of March. = But > of course I'm already looking into Rmock at the moment at home. And at ho= me > I've already added a local Maven 2 repository with Rmock in it, like you > suggested, and for the time being it works perfectly. :) > > Greetings, > Tim > > > Ps. If anyone is interested in how I've set it up, drop me an email (or t= his > list) and I'll try to help you out. > > > > > -----Original Message----- > From: rmo...@li... > [mailto:rmo...@li...] On Behalf Of Daniel Brol= und > Sent: donderdag 9 februari 2006 22:38 > To: t.b...@qu... > Cc: rmo...@li... > Subject: Re: [Rmock-users] Maven 2 support > > Hello Tim! > We're glad you found something you like! :-) > > We have been talking about adding RMock to the maven repositories for qui= te > a while now, and your request will just push us over the edge... > :-) I'll try to get it up there a.s.p. > > If you'd like to start using it as if it was on a maven site I guess you > could create a local maven repository (like ${basedir}/mavenrepo and put > /rmock/jars/rmock-2.0.xxxxx.jar in there) and add that url to the configu= red > list of maven repositories. I haven't done that in maven 2, but it works > fine in maven 1 (hence the syntax might be maven > 1 specific). But you probably already knew that... > > We would also be happy to recieve your feedback on how RMock works for yo= u > and to help you out if you have any problems with it. > > Cheers > Daniel > > > On 2/9/06, t.b...@qu... <t.b...@qu...> wrote: > > Dear RMock users (and developers), > > > > A couple of days ago I found out about RMock and was quite surprised by > its wide range of features. Because of its many features and flexibility = I > would love to start using RMock in a new project the company I work for i= s > about to start. But this new project will use Maven 2 and for as far as I > know, RMock isn't yet uploaded to the global Maven 2 repositories. Does > anyone know if this will happen any time soon, maybe with the final 2.0.0 > release? > > > > Yours sincerely, > > Tim Blommerde > > > > > > ------------------------------------------------------- > > This SF.net email is sponsored by: Splunk Inc. Do you grep through log > > files for problems? Stop! Download the new AJAX search engine that > > makes searching your log files as easy as surfing the web. DOWNLOAD > SPLUNK! > > http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D103432&bid=3D230486&dat= =3D1216 > > 42 _______________________________________________ > > Rmock-users mailing list > > Rmo...@li... > > https://lists.sourceforge.net/lists/listinfo/rmock-users > > > > > -- > __________________________ > Dan...@Gm... > > > ------------------------------------------------------- > This SF.net email is sponsored by: Splunk Inc. Do you grep through log fi= les > for problems? Stop! Download the new AJAX search engine that makes > searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! > http://sel.as-us.falkag.net/sel?cmd=3Dk&kid=103432&bid#0486&dat=121642 > _______________________________________________ > Rmock-users mailing list > Rmo...@li... > https://lists.sourceforge.net/lists/listinfo/rmock-users > > -- __________________________ Dan...@Gm... |
From: Joakim O. <joa...@gm...> - 2006-02-18 18:02:47
|
Hi Thomas, Don't worry about a delayed response, we are happy for any feedback early or late and our biggest concern right now is the time to implement them. We are still really busy with finalizing the first alpha of TDDoc and we have had less time than usual both for rMock and TDDoc. I think I can follow what you mean (what I write below will hopefully indicate that), and here is how I suggest to acomplish that with the section approach: protected void setUp() throws Exception { super.setUp(); beginSection(s.unordered("placeholder"); // now there is a placeholder that you can override to insert expectations here endSection(); _mock =3D mock(MyInterface.class, "mock"); _mock.method1(""); modify.multiplicity(expect.atLeast(0)).args(is.ANYTHING); } public void testXXX() { overrideSection("placeholder", s.unordered("testXXX")); { _mock.method1("aaa"); modify.returnValue("bbb"); _mock.method1("ccc"); modify.returnValue("ddd"); } endSection(); startVerification(); ObjectUnderTest obj =3D new ObjectUnderTest(_mock); obj.doSomething(); // do verification here } I think that this shows clearly that something fishy is going on in testXxx and it allows you to add any number of expectations in the overriding section aswel as specifying if you care about the order of all/some/none of the added expectations using sections. The above is the equivalent of this test (written in only one test method with only one expectation: public void testXxx() { _mock =3D mock(MyInterface.class, "mock"); beginSection(s.unordered("testXXX")); { _mock.method1("aaa"); modify.returnValue("bbb"); _mock.method1("ccc"); modify.returnValue("ddd"); } endSection(); _mock.method1(""); modify.multiplicity(expect.atLeast(0)).args(is.ANYTHING); startVerification(); ObjectUnderTest obj =3D new ObjectUnderTest(_mock); obj.doSomething(); // do verification here } Don't worry about the begin/end section, when you use an unordered section within an unordered section (which is what the default root section that rMock defines for you is) it will work the same as if the expectations where directly in the root section except that they will show within a section in any rMock error message. In this case it stresses the fact that they were added in the testXxx method so you know what was in setup and what was overridden. I hope and beleive that this would help you acomplish what you want. /J |
From: Ziem, T. <Tho...@t-...> - 2006-02-18 15:56:35
|
Hi Joakim, sorry for the delayed response. I don't know if your suggestion will cover the use case I posted before. What I'm looking for is a possibility to define some general expectations in setUp(). For example each call to method1() of my mocked interface with any parameters shall return NULL: protected void setUp() throws Exception { super.setUp(); _mock = mock(MyInterface.class, "mock"); _mock.method1(""); modify.multiplicity(expect.atLeast(0)).args(is.ANYTHING); } Then I will define some additional expectations in testXXX() like this: public void testXXX() { _mock.method1("aaa"); modify.returnValue("bbb"); _mock.method1("ccc"); modify.returnValue("ddd"); startVerification(); ObjectUnderTest obj = new ObjectUnderTest(_mock); obj.doSomething(); // do verification here } If now the object under test calls method1() of my mocked interface than it should get the return values which I defined in testXXX(). All other calls to method1() with any other parameters should return NULL which I defined in setUp(). I hope you can follow my lines (please excuse my english). Regards, Thomas Joakim Ohlrogge wrote: > Hi List! > > A while ago Thomas Ziem asked for the posibility to overide > expectaions. Or more particulary to have something similar to the > JMock stub functionality. The benefit I see with that type of > functionality is that it is easier to create a more general purpose > setup for your tests. > > The suggestion was to make some expectations overridable, something like this: > protected void setUp() throws Exception { > super.setUp(); > _mock = mock(MyObject.class, "mock"); > _mock.method1(""); > > modify.overidable("id").multiplicity(expect.atLeast(0)).args(is.ANYTHING); > } > > public void testMethod1() { > _mock.method1("aaa"); > modify.overrides("id").returnValue("bbb"); // replaces the overidable expectation > } > > I just fixed a bug with sections and I came up with someting that > would acomplish the same but in my opinion be more flexible and clear. > I would like some input on this: > > > protected void setUp() throws Exception { > super.setUp(); > _mock = mock(MyObject.class, "mock"); > > beginSection(s.unordered("placeHolder"); { > _mock.method1(""); > modify.multiplicity(expect.atLeast(0)).args(is.ANYTHING); > } > endSection(); > } > > public void testOverride() { > overrideSection("placeHolder", s.unordered("overidingSection"); { > _mock.method1("aaa"); > modify.returnValue("bbb"); // replaces the overidable expectation > } > endSection(); > > startVerification(); > > assertThat(_mock.method1("aaa"), is.eq("bbb")); > expectThatExceptionThrown(is.instanceOf(UnexpectedException.class)); > mock.method1("aaa"); > } > > > > This would allow you to define an expectation structure in your > setup-method using sections and then be able to replace sections in > that structire in subsequent tests. This would be useful for cases > where your expectations look something like this: > > staticExpectations > ... > changes per test > ... > staticExpectations > > In that case you could define the static expectations before and after > the changing expectations and overide the changing expectations with > any number of expectations (different ones in each test). > > I think that this would enable virtually the same possibilities as > JMocks stub functionality and be less messy to follow than the > previously suggested override mechanism. > > It would also be possibly to have an extendSection("id") functionality > that would simply add ore expectations to a previously defined one. > > What do you say list-members, does this sound like something useful. > Is it easier or harder to understand than the previously suggested > override mechanism. Can you acomplish the same with this suggestion or > is it limiting in some unfortunate way I have not yet thought of? > > /Joakim Ohlrogge |
From: Joakim O. <joa...@gm...> - 2006-02-11 17:12:47
|
Hi List! A while ago Thomas Ziem asked for the posibility to overide expectaions. Or more particulary to have something similar to the JMock stub functionality. The benefit I see with that type of functionality is that it is easier to create a more general purpose setup for your tests. The suggestion was to make some expectations overridable, something like th= is: protected void setUp() throws Exception { super.setUp(); _mock =3D mock(MyObject.class, "mock"); _mock.method1(""); modify.overidable("id").multiplicity(expect.atLeast(0)).args(is.ANYTHING)= ; } public void testMethod1() { _mock.method1("aaa"); modify.overrides("id").returnValue("bbb"); // replaces the overidable expectation } I just fixed a bug with sections and I came up with someting that would acomplish the same but in my opinion be more flexible and clear. I would like some input on this: protected void setUp() throws Exception { super.setUp(); _mock =3D mock(MyObject.class, "mock"); beginSection(s.unordered("placeHolder"); { _mock.method1(""); modify.multiplicity(expect.atLeast(0)).args(is.ANYTHING); } endSection(); } public void testOverride() { overrideSection("placeHolder", s.unordered("overidingSection"); { _mock.method1("aaa"); modify.returnValue("bbb"); // replaces the overidable expectation } endSection(); startVerification(); assertThat(_mock.method1("aaa"), is.eq("bbb")); expectThatExceptionThrown(is.instanceOf(UnexpectedException.class)); mock.method1("aaa"); } This would allow you to define an expectation structure in your setup-method using sections and then be able to replace sections in that structire in subsequent tests. This would be useful for cases where your expectations look something like this: staticExpectations ... changes per test ... staticExpectations In that case you could define the static expectations before and after the changing expectations and overide the changing expectations with any number of expectations (different ones in each test). I think that this would enable virtually the same possibilities as JMocks stub functionality and be less messy to follow than the previously suggested override mechanism. It would also be possibly to have an extendSection("id") functionality that would simply add ore expectations to a previously defined one. What do you say list-members, does this sound like something useful. Is it easier or harder to understand than the previously suggested override mechanism. Can you acomplish the same with this suggestion or is it limiting in some unfortunate way I have not yet thought of? /Joakim Ohlrogge |
From: Tim B. <t.b...@qu...> - 2006-02-10 07:16:13
|
Hello Daniel, Thanks for replying so quickly and of course for the help you offered. = The project I referred to will probably start around the beginning of March. = But of course I'm already looking into Rmock at the moment at home. And at = home I've already added a local Maven 2 repository with Rmock in it, like you suggested, and for the time being it works perfectly. :) Greetings, Tim Ps. If anyone is interested in how I've set it up, drop me an email (or = this list) and I'll try to help you out. -----Original Message----- From: rmo...@li... [mailto:rmo...@li...] On Behalf Of Daniel = Brolund Sent: donderdag 9 februari 2006 22:38 To: t.b...@qu... Cc: rmo...@li... Subject: Re: [Rmock-users] Maven 2 support Hello Tim! We're glad you found something you like! :-) We have been talking about adding RMock to the maven repositories for = quite a while now, and your request will just push us over the edge... :-) I'll try to get it up there a.s.p. If you'd like to start using it as if it was on a maven site I guess you could create a local maven repository (like ${basedir}/mavenrepo and put /rmock/jars/rmock-2.0.xxxxx.jar in there) and add that url to the = configured list of maven repositories. I haven't done that in maven 2, but it works fine in maven 1 (hence the syntax might be maven 1 specific). But you probably already knew that... We would also be happy to recieve your feedback on how RMock works for = you and to help you out if you have any problems with it. Cheers Daniel On 2/9/06, t.b...@qu... <t.b...@qu...> wrote: > Dear RMock users (and developers), > > A couple of days ago I found out about RMock and was quite surprised = by its wide range of features. Because of its many features and flexibility = I would love to start using RMock in a new project the company I work for = is about to start. But this new project will use Maven 2 and for as far as = I know, RMock isn't yet uploaded to the global Maven 2 repositories. Does anyone know if this will happen any time soon, maybe with the final = 2.0.0 release? > > Yours sincerely, > Tim Blommerde > > > ------------------------------------------------------- > This SF.net email is sponsored by: Splunk Inc. Do you grep through log = > files for problems? Stop! Download the new AJAX search engine that=20 > makes searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! > = http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D103432&bid=3D230486&dat=3D= 1216 > 42 _______________________________________________ > Rmock-users mailing list > Rmo...@li... > https://lists.sourceforge.net/lists/listinfo/rmock-users > -- __________________________ Dan...@Gm... ------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Do you grep through log = files for problems? Stop! Download the new AJAX search engine that makes searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! http://sel.as-us.falkag.net/sel?cmd=3Dk&kid=103432&bid#0486&dat=121642 _______________________________________________ Rmock-users mailing list Rmo...@li... https://lists.sourceforge.net/lists/listinfo/rmock-users |
From: Daniel B. <dan...@gm...> - 2006-02-09 21:44:42
|
Hello Tim! We're glad you found something you like! :-) We have been talking about adding RMock to the maven repositories for quite a while now, and your request will just push us over the edge... :-) I'll try to get it up there a.s.p. If you'd like to start using it as if it was on a maven site I guess you could create a local maven repository (like ${basedir}/mavenrepo and put /rmock/jars/rmock-2.0.xxxxx.jar in there) and add that url to the configured list of maven repositories. I haven't done that in maven 2, but it works fine in maven 1 (hence the syntax might be maven 1 specific). But you probably already knew that... We would also be happy to recieve your feedback on how RMock works for you and to help you out if you have any problems with it. Cheers Daniel On 2/9/06, t.b...@qu... <t.b...@qu...> wrote: > Dear RMock users (and developers), > > A couple of days ago I found out about RMock and was quite surprised by i= ts wide range of features. Because of its many features and flexibility I w= ould love to start using RMock in a new project the company I work for is a= bout to start. But this new project will use Maven 2 and for as far as I kn= ow, RMock isn't yet uploaded to the global Maven 2 repositories. Does anyon= e know if this will happen any time soon, maybe with the final 2.0.0 releas= e? > > Yours sincerely, > Tim Blommerde > > > ------------------------------------------------------- > This SF.net email is sponsored by: Splunk Inc. Do you grep through log fi= les > for problems? Stop! Download the new AJAX search engine that makes > searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! > http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D103432&bid=3D230486&dat= =3D121642 > _______________________________________________ > Rmock-users mailing list > Rmo...@li... > https://lists.sourceforge.net/lists/listinfo/rmock-users > -- __________________________ Dan...@Gm... |
From: <t.b...@qu...> - 2006-02-09 09:18:56
|
Dear RMock users (and developers), A couple of days ago I found out about RMock and was quite surprised by its wide range of features. Because of its many features and flexibility I would love to start using RMock in a new project the company I work for is about to start. But this new project will use Maven 2 and for as far as I know, RMock isn't yet uploaded to the global Maven 2 repositories. Does anyone know if this will happen any time soon, maybe with the final 2.0.0 release? Yours sincerely, Tim Blommerde |
From: Joakim O. <joa...@gm...> - 2006-01-31 12:04:43
|
See comments below: > A reset() will probably help a lot for the use-cases I have in mind. Yes, I can see some value in a reset() too eventhough I haven't really missed it. But I didn't really miss intercept either until I got used to it in rMock so that can change when it is there. > I still feel a little uncomfortable about the constrained life-cycle > for mocks. In general in Java I can create and destroy objects > as needed to implement some functionality and I may create these > objects on demand in response to outcomes from previous steps. > In general, I can't predict which objects will be needed for any > given run in advance. With RMock, the life-cycle changes. > All mock objects which I need for any given run must be determined > and created in advance. In my opinion one of the main goals with test code is that it should be simple, both to be free from errors and to be easy to understand at "first glance". A lot of things that you could not live without when implementing business logic is not needed in a test case. Shouldn't the tests test something that is predictable by nature? That doesn't mean that you need to be able to predict all ins and out when you start writing the test though, I tend to add mocks, tests and new interfaces as I discover them. > > At first I thought this would be too restrictive but perhaps it > is just a style issue and RMock users would just need to become > accustomed to this style. Certainly in the initial counter > examples I came up with it was possible to turn them into > different tests each of which exercised a particular path. > In many cases this involved writing more test cases and would > require discipline to avoid duplication but arguably the test > cases are clearer. I do agree that rMock dictates a certain style. This has both pros and cons. A defenite benefit is that test cases, regardless of who wrote them, will have a certain structure. Of course it is till possible to write really crappy tests. You can just take a few things more for granted when you see one :) > I'll have a bit more of a think about this > and see if I can find any examples which must have different > life-cycles for two different mocks. I need to think too, I have not yet come across such a case but I may be too contempt working around such cases. Just to give you some idea how I use rMock and where the style comes from: I have only used rMock in unit-tests and in unit-tests I have arived to the same conclusion as is presented in this paper: http://www.jmock.org/oopsla2004.pdf, that mocks are more useful to test interactions in your system than they are testing iteractions between your system and other systems. I have started to look upon classes like complex objects and leaves. Complex objects are those that interact with other objects. Leaves are those that interact with no other objects. Leaves are best tested using statebased testing, complex objects are best tested using interaction based testing (possibly combined with statebased testing). From this point of view a database is a leaf for a Java-system. If you try to test one class at the time, mocking all dependencies, you usually end up with plentiful but very simple test cases. Your implementations tend to become more simple and the complexity will be in the systems relations (how the different objects are assemled to iteract with eachother). If, while doing this kind of testing I found myself in a situation where I needed different lifecycles for different mocks I would consider that to be a "smell" that either my test is wrong or my implementation is wrong. I realize that system testing is not that simple. It would be nice to be able to support that kind of testing too but it must be suported in such a way so that the primary type of testing "need driven development" does not suffer (like by making the framework extendable in that way). > Is there anywhere that talks about what your end goal is in more detail? > I would definitely be interested in knowing more and perhaps helping if > I can find the time. > rMock is mainly developed by two developers, my self and Daniel Brolund. We have a worked a lot together over the years and are very much in synch about our ideas and where we want to go. That's one of the reasons that we are not as good as we should to comunicate our=20 plans in public. I think that our first step would be to define our values that guide us when we develop rMock, from that anything is possible really. We have alot of ideas all the time, some of them should be worth presenting :) We will come back with more concrete tasks that we have on our list shortly, we just need to wrap up TDDoc to something useful (that we have already promised several weeks now). Thanks for your interest and your input! /Joakim |
From: Paul K. <pa...@as...> - 2006-01-31 10:27:08
|
In general, the "FrameworkTests" and "PatternTests" sound very useful for integration, acceptance and state-based unit tests - perhaps less useful for mocks. It would be interesting to see if you could mimic some of the functionality of Agitar's Agitator (and Domain Expert API). I'll have a bit more of a think about this at a later date. Cheers, Paul. Joakim Ohlrogge wrote: >> I can see the attraction to keeping to the simple model which >> RMock supports but I still think it is very restrictive. In the >> example below you unravelled the loop to turn it into a non-OO >> example. I doubt you can always do this. I used a loop to >> try to indicate that in general you wouldn't know how many >> things you might have to loop through. In general, the data may >> come from a properties file or might come from a database. > > Another option that we have been discussing some time ago would be to > extend on the DynamicSuites functionality. Then you could achieve > something like: > > find all proeprtyFiles named "testForClassXXXX*" for each property in > each file create an isntance of a "patternTest" with data from the > propertyfile as parameters. > > > > A more concete example that we have discussed is: > > find all implementors of "Constraint", create an instance of > TestBasicConstraintFunctionality for each found constraint. > > The basicConstraintFunctionality would then try the constraint with > null, "", "Some other string", Integer.MAX_VALUE etc to make sure that > the constraint functions and does not throw any ArrayIndexOutOfBounds, > ClassCast, NullPointer, IllegalArgument etc exceptions (which is > importrant for constraints) > > We have called this kind of test "FrameWorkTests" or "PatternTests". > What is your input on that kind of functionality? It is possible that > you can create more data-driven teests in this way and could perhaps > open up some new options to attack more tricky to test problems. > > Just some random, possibly irelevant, unstructured, thoughts of mine... > Cheers! > /Joakim > > |
From: Paul K. <pa...@as...> - 2006-01-31 10:24:26
|
Joakim Ohlrogge wrote: > As I said in my previous mail we will support reset, which would make > it possible to do the looping you request. What will not be supported > out of the box is to have several different mocks be in different > states at one moment, do you find this too restrictive? A reset() will probably help a lot for the use-cases I have in mind. I still feel a little uncomfortable about the constrained life-cycle for mocks. In general in Java I can create and destroy objects as needed to implement some functionality and I may create these objects on demand in response to outcomes from previous steps. In general, I can't predict which objects will be needed for any given run in advance. With RMock, the life-cycle changes. All mock objects which I need for any given run must be determined and created in advance. At first I thought this would be too restrictive but perhaps it is just a style issue and RMock users would just need to become accustomed to this style. Certainly in the initial counter examples I came up with it was possible to turn them into different tests each of which exercised a particular path. In many cases this involved writing more test cases and would require discipline to avoid duplication but arguably the test cases are clearer. I'll have a bit more of a think about this and see if I can find any examples which must have different life-cycles for two different mocks. > However, we will make an effort to make it possible to extend rMock in > such a way that it would be possible (read subclass RMockTestCase or > similar). I looked into that yesterday and it does not look too hard. Sounds cool. > We are currently focusing most efforts on tddoc since we feel that we > have something that crawls within reach and since we are only two > developers at the moment it takes most of the sparetime we have :) > > Our main goal has been to create a UnitTesting mocking framework that > is as self describing (with tddoc self documenting) and easy to use as > possible. Hopefully it can be used in situations beyond that but we > have not tried that ourselves so it is likely that rMock lacks > functionality in that area. Is there anywhere that talks about what your end goal is in more detail? I would definitely be interested in knowing more and perhaps helping if I can find the time. Paul. |
From: Joakim O. <joa...@gm...> - 2006-01-30 15:09:46
|
> I can see the attraction to keeping to the simple model which > RMock supports but I still think it is very restrictive. In the > example below you unravelled the loop to turn it into a non-OO > example. I doubt you can always do this. I used a loop to > try to indicate that in general you wouldn't know how many > things you might have to loop through. In general, the data may > come from a properties file or might come from a database. Another option that we have been discussing some time ago would be to extend on the DynamicSuites functionality. Then you could achieve something like: find all proeprtyFiles named "testForClassXXXX*" for each property in each file create an isntance of a "patternTest" with data from the propertyfile as parameters. A more concete example that we have discussed is: find all implementors of "Constraint", create an instance of TestBasicConstraintFunctionality for each found constraint. The basicConstraintFunctionality would then try the constraint with null, "", "Some other string", Integer.MAX_VALUE etc to make sure that the constraint functions and does not throw any ArrayIndexOutOfBounds, ClassCast, NullPointer, IllegalArgument etc exceptions (which is importrant for constraints) We have called this kind of test "FrameWorkTests" or "PatternTests". What is your input on that kind of functionality? It is possible that you can create more data-driven teests in this way and could perhaps open up some new options to attack more tricky to test problems. Just some random, possibly irelevant, unstructured, thoughts of mine... Cheers! /Joakim |
From: Paul K. <pa...@as...> - 2006-01-30 13:51:16
|
I can see the attraction to keeping to the simple model which RMock supports but I still think it is very restrictive. In the example below you unravelled the loop to turn it into a non-OO example. I doubt you can always do this. I used a loop to try to indicate that in general you wouldn't know how many things you might have to loop through. In general, the data may come from a properties file or might come from a database. If your target audience for RMock is strictly unit tests and you are using TDD and you have control over all the packages/classes you are using and they have been created with all the things which make unit testing easy (e.g. dependency injection or similar) than you will probably get away with the functional style. If you also wish to support integration tests where some of the dependencies for the test need to be mocked out then I don't think the current approach alone will be sufficient. For example, I may need to create a database connection and I may need a mock for one of the parameters because in my integration test the path I will be following doesn't use all of the parameters. Now I wish to read back all of the rows in a particular table and depending on the value I read back I wish to invoke different functionality corresponding to different paths of execution. In this case the connection helper mock and subsequent mocks can not be known in advance and have different lifecycles. Trying to force this scenario into a functional view of the world will likely lead to extremely convoluted code. Now this example is a bit of a stretch but it kind of gives you the idea. I certainly wouldn't start out trying to test things this way but sometimes there are parts of the systems you have to deal with that are OO in nature and the most natural way to test them is in an OO fashion. Regarding giving you feedback - I will be happy to if I have time - just some background info: I have spent the last approx 12 months in a team of approx 10 developers doing strict TDD/XP (100% coverage, 0 checkstyle violations, 0% duplication, radical metrics). The system we built included Distributed JVMs, JMS, Axis, PDF Templating Engines, Printing, Emails and numerous other technologies. We did make use of some nice technologies, Spring, Hibernate etc but also were forced to deal with some horrible (to test) ones. I can't imagine achieving what we did without an OO style mocking framework (we did use a bit of MockRunner as well but mostly JMock). JMock was very good but its style makes your IDE work very hard when you do certain kinds of refactoring and for other kinds of refactoring makes you work very hard!! :-) I imagine many of the standard mocking that we did would look considerably simpler and refactor better using RMock. Hence my interest. I am also interested in some of the "planned features" alluded to (tddoc and additional aspect stuff and others). We also run an open source testing tools courses where we compare EasyMock(1/2), jMock, MockRunner etc. Also, I recently integrated some Email testing steps into an open source testing tool called webtest. Its claim to fame is that it lets you write acceptance tests in XML (well ant really with all the power that ant tasks give you). The build environment doesn't have an email/pop3 server easily available so I had to mock out most of the JavaMail functionality. It is definitely an API designed prior to the current thinking on dependency injection and also prior to thinking about consistent use of interfaces. Over the weekend I used RMock to write the tests and still managed to get reasonably coverage. :-) The source code for those tests is available if anyone is interested. Details of webtest: http://webtest.canoo.com/ Details of Email steps: http://webtest.canoo.com/webtest/manual/syntaxEmail.html Details of coverage: http://webtest.canoo.com/webtest/clover/index.html (source code available by clicking on clover links or through fisheye or through CVS) Cheers, Paul. Joakim Ohlrogge wrote: > Hi Paul, > > You're right it doesn't support that style. Thanks for the example it > showed me more clearly what you are after. In that particular example > I would still go for one test method for each indata/expectation > combination as shown below but you convinced me that the reset > functionality can be useful. I'll get back to that after this example: > > public class MyTest extends RMockTestCase { > private String input; > private int expected; > private ITokenizer mock; > > protected void setUp() { > mock = intercept(SingleLineStringTokenizer.class, "id"); > } > > public void testEmptyString() { > input=""; > expected = 0; > } > > public void testOneWord() { > input="one"; > expected = 1; > } > > public void testTwoWordsSpace() { > input="one two"; > expected = 2; > } > > public void testTwoWordsNewLine) { > mock = intercept(MultiLineRegexpTokenizer.class, "multiLineTokenizer"); > input="one\ntwo"; > expected = 2; > } > > protected void preValidation() { > mock.count(null); > modify().args(is.NOT_NULL).forward(); > > startVerfivation(); > > WordCounter classUnderTest = new WordCounter(mock); > assertThat(classUnderTest.countWords(input), is.eq(expected)); > } > } > > Just a few remarks about what I changed: > > * I noticed that you changed the class to be mocked in an if > statement, I understood this as you were actually using different > implementations of ITokenizer so I changed mock to intercept and added > an expectation with a forward action to make it test something. Maybe > I overlooked something? > > * I removed the if statement and overrode the mock in the new-line testcase. > > I would encourage something like the test above eventhough it means a > bit more of typing. To me the above is more descriptive and you don't > have to decode in your head what the code does to understand what is > tested, it says so clearly in the test methods. > > Having that said, I do realize that that is a subjective opinion of > mine and that your example shows why a reset would be useful. I > discussed this with a Daniel and we concluded that we can support > reset without violating any principles in the rMock design. > > In any case, pre/postValidation events will be added to support the > example I just gave, we realized that both of us missed that option > several times already, thank you for opening our eyes :) > > We will support reset as soon as we have time to implement it > (hopefully before next sunday). The initial reset functionality will > work in this way: > > - reset resets all mocks in the engine at once. > - reset implicitly validates all mocks before they are reset. > - reset clears all mock information > > This still follows the setup-execute-verify workflow with the addition > that it allows several runs withing one test-method: > (setup-execute-verify)+. It would make rMock more useful without > making it harder to use. > > I have seen EasyMocks approach before and while being more flexible it > also removes some clairity. With easymock two different mocks can be > in different states within the same testcase. In a recording mock > framework this can be somewhat confusing. Knowing that all mocks are > in the same state always removes some questions when you are looking > into why a test fails. > > It should be possible though to instatiate two engines pretty much as > you did with your controller example in easymock and acheive the same. > That is something that we don't want to encourage by adding it to > RMockTestCase but we will make sure that it can be done if you wish to > subclass RMockTestCase (if it is not already possible). > > Thanks for your input, it is apreachiated. > > You seem to have some experience from several mocking frameworks. It > would be very interesting, if you could spare some time, to hear what > you like in rMock and what you like better in other frameworks. It > would be valuable input for us when we decide in which order to add > which features. > > Thanks in advance! > /Joakim |
From: Joakim O. <joa...@gm...> - 2006-01-29 18:59:09
|
Hi Paul, You're right it doesn't support that style. Thanks for the example it showed me more clearly what you are after. In that particular example I would still go for one test method for each indata/expectation combination as shown below but you convinced me that the reset functionality can be useful. I'll get back to that after this example: public class MyTest extends RMockTestCase { private String input; private int expected; private ITokenizer mock; protected void setUp() { mock =3D intercept(SingleLineStringTokenizer.class, "id"); } public void testEmptyString() { input=3D""; expected =3D 0; } public void testOneWord() { input=3D"one"; expected =3D 1; } public void testTwoWordsSpace() { input=3D"one two"; expected =3D 2; } public void testTwoWordsNewLine) { mock =3D intercept(MultiLineRegexpTokenizer.class, "multiLineTokeni= zer"); input=3D"one\ntwo"; expected =3D 2; } protected void preValidation() { mock.count(null); modify().args(is.NOT_NULL).forward(); startVerfivation(); WordCounter classUnderTest =3D new WordCounter(mock); assertThat(classUnderTest.countWords(input), is.eq(expected)); } } Just a few remarks about what I changed: * I noticed that you changed the class to be mocked in an if statement, I understood this as you were actually using different implementations of ITokenizer so I changed mock to intercept and added an expectation with a forward action to make it test something. Maybe I overlooked something? * I removed the if statement and overrode the mock in the new-line testcase= . I would encourage something like the test above eventhough it means a bit more of typing. To me the above is more descriptive and you don't have to decode in your head what the code does to understand what is tested, it says so clearly in the test methods. Having that said, I do realize that that is a subjective opinion of mine and that your example shows why a reset would be useful. I discussed this with a Daniel and we concluded that we can support reset without violating any principles in the rMock design. In any case, pre/postValidation events will be added to support the example I just gave, we realized that both of us missed that option several times already, thank you for opening our eyes :) We will support reset as soon as we have time to implement it (hopefully before next sunday). The initial reset functionality will work in this way: - reset resets all mocks in the engine at once. - reset implicitly validates all mocks before they are reset. - reset clears all mock information This still follows the setup-execute-verify workflow with the addition that it allows several runs withing one test-method: (setup-execute-verify)+. It would make rMock more useful without making it harder to use. I have seen EasyMocks approach before and while being more flexible it also removes some clairity. With easymock two different mocks can be in different states within the same testcase. In a recording mock framework this can be somewhat confusing. Knowing that all mocks are in the same state always removes some questions when you are looking into why a test fails. It should be possible though to instatiate two engines pretty much as you did with your controller example in easymock and acheive the same. That is something that we don't want to encourage by adding it to RMockTestCase but we will make sure that it can be done if you wish to subclass RMockTestCase (if it is not already possible). Thanks for your input, it is apreachiated. You seem to have some experience from several mocking frameworks. It would be very interesting, if you could spare some time, to hear what you like in rMock and what you like better in other frameworks. It would be valuable input for us when we decide in which order to add which features. Thanks in advance! /Joakim |
From: Paul K. <pa...@as...> - 2006-01-28 00:55:04
|
I am not sure I get what I want with your suggestion. How would the following example work: public class MyTest extends RMockTestCase { private static final String[] input = {"", "oneword", "two words", "two\nwords"}; private static final int[] expectedNumWords = {0, 1, 2, 2}; public void testCountWords() { for (int i = 0; i < input.length; i++) { checkCountWords(expectedNumWords[i], input[i]); } } private void checkCountWords(final int expectedNumWords, final String words) { final ITokenizer mock; if (words.indexOf("\n") > -1) { mock = mock(MultiLineRegexpTokenizer.class, "id"); } else { mock = mock(SingleLineStringTokenizer.class, "id"); } WordCounter classUnderTest = new WordCounter(mock); assertThat(classUnderTest.countWords(words), is.eq(expectedNumWords)); } } It is a little contrived but hopefully indicates the issue. Cheers, Paul. Joakim Ohlrogge wrote: > Hi Paul, > > I have been doing some more thinking and here is a suggestion to > support something similar to what you do. Forst let me tell you what I > understood that you want to achieve and see if you agree: > > * You want to be able to run the same test with different indata. > * You want to have the same expectations with different values in each case > * You want to do the same asserts with different expected values > depending on the > values of the expectation setup. > > I considered a reset feature but aboned that path for the following main reason. > * reset would give the posibility to break the setup - run - verify > workflow of rmock, something I feel is an important part of the rMock > filosophy. as a consequence of that you cannot assume that everything > above startVerification is setup and everything after is verification. > That would in my opinion make rMock testcases a bit harder to > understand. > > > I do however see value in what you suggest and thought about how to be > able to achieve that without violating the workflow and here is a > suggestion to consider: > > > introduce preValidation and postValidation methods so that an rmock > testcase would have the following callbacks in this order: > > setup > **the test<Name> method is run here** > preValidation > **rmock validates expectaions here** > postValidation > tearDown <- teardown is in a finally block which does not make it > suitable for asserts > > That would enable the possibility to write something like this: > > > public class SomeTest extends RMockTestCase { > private SomeType expected; > > void setup() { > // create mocks > } > > public void testCheckSomething1() { > setupMocks(param1); > expected = expected1; > } > > public void testCheckSomething2() { > setupMocks(param2); > expected = expected2; > } > > public void testCheckSomething3() { > setupMocks(param3); > expected = expected3; > } > > public void preValidation() { > startVerification(); > // do something > assertThat(actual, is.eq(expected); > } > } > > Granted this means a bit more typing but it does remove duplicate code > and also has some other benefits: > * when a sertain value combination fails, junit will report which > combination as a separate test. > * The flow follows a well deined pattern since it is supported by the > framework and thereby reduces possible complexity somewhat. > * Honors the "one test, one assert rule" (if that feels better :)) > > I hope that this feels like a suficient solution for you. Any input? > Regards! > Joakim |
From: Paul K. <pa...@as...> - 2006-01-28 00:27:48
|
Thanks Joakim, Overall I am very impressed with rMock but it seems a shame to support only functional and not object semantics all the time. As an alternative which supports both styles, EasyMock 2 allows: IMyInterface mock = createStrictMock(IMyInterface.class); replay(mock); verify(mock); reset(mock); as well as this object-style equivalent: IMocksControl ctrl = createStrictControl(); IMyInterface mock = ctrl.createMock(IMyInterface.class); ctrl.replay(); ctrl.verify(); ctrl.reset(); If the business logic inside RMockTestCase, e.g. engine, listeners, proxyFactory etc. was all placed into its own class, e.g. RMockControl, then it might be possible to have something like: Control ctrl = createControl(); // returns instance of RMockControl IMyInterface myMock = ctrl.mock(IMyInterface.class, "myMock"); ctrl.startVerification(); // would call engine.beginVerify() in ctrl ctrl.verify(); // would call engine.endVerify() inside ctrl ctrl.reset(); // would do proxyFactory.clear() and you would need an // engine.reset() to put the engine back in setup mode RMockTestCase could be simplified to just use a delegate of RMockControl. Also, createControl() could take a boolean (auto/manual) or you could have createManualControl() or createAutoControl(). RMockTestCase could keep track of created controls. Auto ones it could call startVerification() and verify() on automatically. This would allow more flexible mock creation (with no need to expose verify etc.): Control ctrl1 = createControl(); // assume default is auto Control ctrl2 = createControl(); // assume default is auto ctrl1.mock(...); ctrl2.mock(...); ctrl1.modify(...); ctrl2.modify(...); If you did a createManualControl() it would be up to you to ensure startVerification() and verify() were called. runBare could still ensure that all created manual controls were in the verify (or post endVerify) state once the test ended etc. There are plenty of options and questions. E.g. for simplification purposes should the object style control only be allowed to control one mock? I.e. give the control an id and have no id parameter in the mock() call? Anyway, it would be a bit of work and I haven't looked into the code in detail yet - I am not sure how all the other parts would be impacted. It would certainly help support the strict TDD approaches I have observed if some kind of object style was available. Cheers, Paul. Joakim Ohlrogge wrote: > Hi Paul, thanks for your mail. > > I can't think of anything obvious that would solve your problem but > your style is new to me so i have to give it some thought before I can > answer. I usually triangulate in several testMethods and try to have > one assert per test (although I don't cry if I have more). > > A reset method would solve your problem but I think that the workflow > of rmock would suffer from such a feature and I can't asess at the > moment if the benefit would be worth the sacrafice. > > In general JMock and EasyMock are more flexible in this sense. We > chose to remove some flexibility to make the tests more strictly > uniform (setup, execute, verify). The downside of that descision is > that some stunts are not possible. > > I will need to digest this before I can give you a suggestion or an opinion. > > /Joakim > > > On 1/27/06, Paul King <pa...@as...> wrote: >> A particular style I have grown used to (mainly using jMock) >> is as follows. First develop a single test: >> >> public void testSomething() { >> setupMocks(params); >> startVerification(); >> // do something >> assertEquals(expected, actual); >> } >> >> Then refactor out the test into a check >> method and triangulate across some desired >> values (usually 2 in non-looping scenarios and >> 3 or more in looping or more complex scenarios): >> >> public void testSomething() { >> checkSomething(params1, expected1); >> checkSomething(params2, expected2); >> checkSomething(params3, expected3); >> } >> >> private void checkSomething(params, expected) { >> setupMocks(params); >> startVerification(); >> // do something >> assertEquals(expected, actual); >> } >> >> >> This obviously won't work when using rMock. >> The setupMocks will declare multiple mocks >> with the same id and I suspect that the multiple >> startVerifications won't work either. >> >> It isn't trivial to extract out just the >> "do something" part of the test - the >> setupMocks itself sets up various nested >> mocks based on the input params. >> >> Can you suggest a way to use the above approach >> using rMock? Perhaps I need a reset() >> method which would make rMock forget about >> all declared mocks and place it back into >> pre-verification mode. >> >> My work-around at the moment is to place >> each checkSomething into its own test - but >> that isn't anywhere near as elegant. >> >> Any thoughts/suggestions? >> >> Thanks, Paul. >> |
From: Joakim O. <joa...@gm...> - 2006-01-27 22:35:52
|
Hi Paul, I have been doing some more thinking and here is a suggestion to support something similar to what you do. Forst let me tell you what I understood that you want to achieve and see if you agree: * You want to be able to run the same test with different indata. * You want to have the same expectations with different values in each case * You want to do the same asserts with different expected values depending on the values of the expectation setup. I considered a reset feature but aboned that path for the following main re= ason. * reset would give the posibility to break the setup - run - verify workflow of rmock, something I feel is an important part of the rMock filosophy. as a consequence of that you cannot assume that everything above startVerification is setup and everything after is verification. That would in my opinion make rMock testcases a bit harder to understand. I do however see value in what you suggest and thought about how to be able to achieve that without violating the workflow and here is a suggestion to consider: introduce preValidation and postValidation methods so that an rmock testcase would have the following callbacks in this order: setup **the test<Name> method is run here** preValidation **rmock validates expectaions here** postValidation tearDown <- teardown is in a finally block which does not make it suitable for asserts That would enable the possibility to write something like this: public class SomeTest extends RMockTestCase { private SomeType expected; void setup() { // create mocks } public void testCheckSomething1() { setupMocks(param1); expected =3D expected1; } public void testCheckSomething2() { setupMocks(param2); expected =3D expected2; } public void testCheckSomething3() { setupMocks(param3); expected =3D expected3; } public void preValidation() { startVerification(); // do something assertThat(actual, is.eq(expected); } } Granted this means a bit more typing but it does remove duplicate code and also has some other benefits: * when a sertain value combination fails, junit will report which combination as a separate test. * The flow follows a well deined pattern since it is supported by the framework and thereby reduces possible complexity somewhat. * Honors the "one test, one assert rule" (if that feels better :)) I hope that this feels like a suficient solution for you. Any input? Regards! Joakim |
From: Joakim O. <joa...@gm...> - 2006-01-27 15:31:42
|
---------- Forwarded message ---------- From: Joakim Ohlrogge <joa...@gm...> Date: Jan 27, 2006 4:11 PM Subject: Re: [Rmock-users] Usage question To: Paul King <pa...@as...> Hi Paul, thanks for your mail. I can't think of anything obvious that would solve your problem but your style is new to me so i have to give it some thought before I can answer. I usually triangulate in several testMethods and try to have one assert per test (although I don't cry if I have more). A reset method would solve your problem but I think that the workflow of rmock would suffer from such a feature and I can't asess at the moment if the benefit would be worth the sacrafice. In general JMock and EasyMock are more flexible in this sense. We chose to remove some flexibility to make the tests more strictly uniform (setup, execute, verify). The downside of that descision is that some stunts are not possible. I will need to digest this before I can give you a suggestion or an opinion= . /Joakim On 1/27/06, Paul King <pa...@as...> wrote: > > A particular style I have grown used to (mainly using jMock) > is as follows. First develop a single test: > > public void testSomething() { > setupMocks(params); > startVerification(); > // do something > assertEquals(expected, actual); > } > > Then refactor out the test into a check > method and triangulate across some desired > values (usually 2 in non-looping scenarios and > 3 or more in looping or more complex scenarios): > > public void testSomething() { > checkSomething(params1, expected1); > checkSomething(params2, expected2); > checkSomething(params3, expected3); > } > > private void checkSomething(params, expected) { > setupMocks(params); > startVerification(); > // do something > assertEquals(expected, actual); > } > > > This obviously won't work when using rMock. > The setupMocks will declare multiple mocks > with the same id and I suspect that the multiple > startVerifications won't work either. > > It isn't trivial to extract out just the > "do something" part of the test - the > setupMocks itself sets up various nested > mocks based on the input params. > > Can you suggest a way to use the above approach > using rMock? Perhaps I need a reset() > method which would make rMock forget about > all declared mocks and place it back into > pre-verification mode. > > My work-around at the moment is to place > each checkSomething into its own test - but > that isn't anywhere near as elegant. > > Any thoughts/suggestions? > > Thanks, Paul. > > > ------------------------------------------------------- > This SF.net email is sponsored by: Splunk Inc. Do you grep through log fi= les > for problems? Stop! Download the new AJAX search engine that makes > searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! > http://sel.as-us.falkag.net/sel?cmd=3Dlnk&kid=3D103432&bid=3D230486&dat= =3D121642 > _______________________________________________ > Rmock-users mailing list > Rmo...@li... > https://lists.sourceforge.net/lists/listinfo/rmock-users > |
From: Paul K. <pa...@as...> - 2006-01-27 14:48:18
|
A particular style I have grown used to (mainly using jMock) is as follows. First develop a single test: public void testSomething() { setupMocks(params); startVerification(); // do something assertEquals(expected, actual); } Then refactor out the test into a check method and triangulate across some desired values (usually 2 in non-looping scenarios and 3 or more in looping or more complex scenarios): public void testSomething() { checkSomething(params1, expected1); checkSomething(params2, expected2); checkSomething(params3, expected3); } private void checkSomething(params, expected) { setupMocks(params); startVerification(); // do something assertEquals(expected, actual); } This obviously won't work when using rMock. The setupMocks will declare multiple mocks with the same id and I suspect that the multiple startVerifications won't work either. It isn't trivial to extract out just the "do something" part of the test - the setupMocks itself sets up various nested mocks based on the input params. Can you suggest a way to use the above approach using rMock? Perhaps I need a reset() method which would make rMock forget about all declared mocks and place it back into pre-verification mode. My work-around at the moment is to place each checkSomething into its own test - but that isn't anywhere near as elegant. Any thoughts/suggestions? Thanks, Paul. |