From: Thomas C. <ald...@ne...> - 2001-08-07 16:35:12
|
Steve "just a quick point to start with. Have you looked at a recent edition of the mock objects library? You might want to align some of your terminology, in particular the distinction between a Verifiable and a Mock" I just looked at a recent edition and very good point. Essentially, you can replace the MockObject interface in the article with com.mock.Verifiable. To give you some context, much of the article comes from a policy file in a project I am working on that started before I read your article, thus the inconsistencies even though your article is cited. I shall align the terminology in the next draft of the article. Tom |
From: Vincent M. <vm...@oc...> - 2001-08-07 16:45:37
|
Hey Steve, could you please repost your answer to Thomas's question to the list as it seems you only answered to him in private and I would like to participate in the discussion as it seems quite interesting ... :-) Thanks -Vincent ----- Original Message ----- From: "Thomas Calivera" <ald...@ne...> To: <moc...@li...> Sent: Tuesday, August 07, 2001 5:33 PM Subject: Re: [Mockobjects-java-users] Advanced Java Patterns For Rigorous Unit Testing DRAFT > Steve > > "just a quick point to start with. Have you looked at a recent edition of > the mock objects library? You might want to align some of your terminology, > in particular the distinction between a Verifiable and a Mock" > > I just looked at a recent edition and very good point. Essentially, you can > replace the MockObject interface in the article with com.mock.Verifiable. To > give you some context, much of the article comes from a policy file in a > project I am working on that started before I read your article, thus the > inconsistencies even though your article is cited. I shall align the > terminology in the next draft of the article. > > Tom > > > _______________________________________________ > Mockobjects-java-users mailing list > Moc...@li... > http://lists.sourceforge.net/lists/listinfo/mockobjects-java-users > |
From: Vincent M. <vm...@oc...> - 2001-08-08 12:56:47
|
I was thinking about unit testing Struts Actions. Introduction ------------ Writing a Struts Action is very simple: you simply have to provide a perform method with the following signature : public ActionForward perform(ActionMapping mapping, ActionForm form, ServletRequest request, ServletResponse response) Thus, in order to use Mock Objects for unit testing your action you have to provide mock implementations of : - ActionMapping, - ActionForm, - ServletRequest, - ServletResponse, - ActionServlet : an instance of this class is provided to your action and you can use it to perforl several things. It can be set by calling the setServlet(ActionServlet) method on your Action class. Problem --------- The issue is that Struts initialize internally a lot of objects and put them in different scopes : session, servlet context, request, ..., which is fine. What it simply means is that if you want to unit test your Action class, you'll need to understand in details how Struts works internally and stuff the session, context, ... with the expected values. To do that you'll have to read the source code and spend quite a lot of time (even though Sturts is really well designed by composition). I think this is a major hurdle for using Mock Objects when your object to test is using APIs that are not yours ... Struts is open source so it is feasible to look a the source. For non open-source framework, it is even harder ... The second objection is that doing all this initialization takes a lot of lines of code and is a tiring process. Now, would it be easier with Cactus ? I think so ... for the following reasons. Here is how you would do it with Cactus : ActionServlet servlet = new ActionServlet(); servlet.init(config); (you'll also have to provide a struts-config.xml file but that's fine as you have to write one for Struts anyway). that's all, Struts is initialized ! You don't need to understand how struts works internally. Of course, you could do the same with Mock Objects but you'll no longer be following the Mock Objects principles. Conclusion ----------- Mock Objects has limitations in the following areas : - when the API to mock is not yours and especially if you don't have access to the source code because :; - it takes time to understand how the API works internally - it takes time for every test to initialize the API environment properly. - it is difficult when your class to test is using an Application (as opposed to a framework). A framework is for exemple a logging framework, it contains no state and no business logic, so it is easy to mock. However a framework like Struts is actually an Application : it has state and it has logic, thus you need to understand its internal functioning to mock it. I would very much like to have you thoughts on that, especially if you don't agree ! :) Thanks -Vincent |
From: Vincent M. <vm...@oc...> - 2001-08-08 14:14:29
|
Let me answer some of my points ... ----- Original Message ----- From: "Vincent Massol" <vm...@oc...> To: <cac...@ja...> Cc: <moc...@li...> Sent: Wednesday, August 08, 2001 1:55 PM Subject: Another point of Mock vs In-Container approach > I was thinking about unit testing Struts Actions. > > Introduction > ------------ > > Writing a Struts Action is very simple: you simply have to provide a perform > method with the following signature : > > public ActionForward perform(ActionMapping mapping, > ActionForm form, > ServletRequest request, > ServletResponse response) > > > Thus, in order to use Mock Objects for unit testing your action you have to > provide mock implementations of : > - ActionMapping, > - ActionForm, > - ServletRequest, > - ServletResponse, > - ActionServlet : an instance of this class is provided to your action and > you can use it to perforl several things. It can be set by calling the > setServlet(ActionServlet) method on your Action class. > > Problem > --------- > > The issue is that Struts initialize internally a lot of objects and put them > in different scopes : session, servlet context, request, ..., which is fine. > What it simply means is that if you want to unit test your Action class, > you'll need to understand in details how Struts works internally and stuff > the session, context, ... with the expected values. To do that you'll have > to read the source code and spend quite a lot of time (even though Sturts is > really well designed by composition). I think this is a major hurdle for > using Mock Objects when your object to test is using APIs that are not yours > ... Struts is open source so it is feasible to look a the source. For non > open-source framework, it is even harder ... well, I don't know what happened to me ... I must have knocked my head somewhere ... because this is not true at all .... Using Mock Object we just need to understand what the public methods return (not how it works internally!) ... > The second objection is that > doing all this initialization takes a lot of lines of code and is a tiring > process. > maybe true ... will need an example though to prove it... > Now, would it be easier with Cactus ? I think so ... for the following > reasons. > Here is how you would do it with Cactus : > > ActionServlet servlet = new ActionServlet(); > servlet.init(config); > this is true! MO cannot beat this ... > (you'll also have to provide a struts-config.xml file but that's fine as you > have to write one for Struts anyway). > that's all, Struts is initialized ! You don't need to understand how struts > works internally. Of course, you could do the same with Mock Objects but > you'll no longer be following the Mock Objects principles. > > Conclusion > ----------- > > Mock Objects has limitations in the following areas : > - when the API to mock is not yours and especially if you don't have access > to the source code because :; > - it takes time to understand how the API works internally no! > - it takes time for every test to initialize the API environment properly. maybe > - it is difficult when your class to test is using an Application (as > opposed to a framework). A framework is for exemple a logging framework, it > contains no state and no business logic, so it is easy to mock. However a > framework like Struts is actually an Application : it has state and it has > logic, thus you need to understand its internal functioning to mock it. not completely sure it is wrong, maybe there is some truth in that... > > I would very much like to have you thoughts on that, especially if you don't > agree ! :) please don't flame me ... :) > Thanks > > -Vincent > > |
From: Vincent M. <vm...@oc...> - 2001-08-08 14:36:12
|
After thinking a bit more, I now understand what I meant and why I said you had to understand internally how Struts work. This is true in some cases and stems from the fact that Struts is using Base classes instead of interfaces and thus these base classes have some logic in them ... You'll understand what I mean below ... Let's take the following example : public final class LogonAction extends Action { public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // Extract attributes we will need Locale locale = getLocale(request); [...] } The getLocale() method is actually implemented in the Action class ... So I can see 2 ways of coping with this : * Solution 1: Create a LogonActionForTest class that extends LogonAction and override the getLocale() method so that it returns what we want, * Solution 2: Read the source, to find that actually Struts looks into the session for a variable that contains the Locale. Then, write something like public void testXXX() { mockSession.put(Action.LOCALE_KEY, <our locale>); myAction.perform(....); ... } If we use the Cactus approach, i.e. initialize ActionServlet as in real (using the struts-config.xml file), this key will be placed by Struts automatically in the session and we won't have to implement either solution 1 or solution 2. Note that we are *not* interested in finding out what happens if they locale is not correctly set as Struts is supposed to handle that and always return a valid Locale. However we are interested in finding out that our code behaves well with different locales. Regarding Mock Object, it seems to me that Solution 1 is more in the spriti of MO. Potential problems with Solution 1 : * It will only work if our Action class is not declared final ... * It will fail if there is some (badly written) code that verifies the class of the Action and expects a LogonAction class (it will get a LogonActionForTest class instead) and not a derived one. Thoughts? Thanks -Vincent ----- Original Message ----- From: "Vincent Massol" <vm...@oc...> To: <cac...@ja...> Sent: Wednesday, August 08, 2001 3:16 PM Subject: Re: Another point of Mock vs In-Container approach > Let me answer some of my points ... > > ----- Original Message ----- > From: "Vincent Massol" <vm...@oc...> > To: <cac...@ja...> > Cc: <moc...@li...> > Sent: Wednesday, August 08, 2001 1:55 PM > Subject: Another point of Mock vs In-Container approach > > > > I was thinking about unit testing Struts Actions. > > > > Introduction > > ------------ > > > > Writing a Struts Action is very simple: you simply have to provide a > perform > > method with the following signature : > > > > public ActionForward perform(ActionMapping mapping, > > ActionForm form, > > ServletRequest request, > > ServletResponse response) > > > > > > Thus, in order to use Mock Objects for unit testing your action you have > to > > provide mock implementations of : > > - ActionMapping, > > - ActionForm, > > - ServletRequest, > > - ServletResponse, > > - ActionServlet : an instance of this class is provided to your action and > > you can use it to perforl several things. It can be set by calling the > > setServlet(ActionServlet) method on your Action class. > > > > Problem > > --------- > > > > The issue is that Struts initialize internally a lot of objects and put > them > > in different scopes : session, servlet context, request, ..., which is > fine. > > What it simply means is that if you want to unit test your Action class, > > you'll need to understand in details how Struts works internally and stuff > > the session, context, ... with the expected values. To do that you'll have > > to read the source code and spend quite a lot of time (even though Sturts > is > > really well designed by composition). I think this is a major hurdle for > > using Mock Objects when your object to test is using APIs that are not > yours > > ... Struts is open source so it is feasible to look a the source. For non > > open-source framework, it is even harder ... > > well, I don't know what happened to me ... I must have knocked my head > somewhere ... because this is not true at all .... Using Mock Object we just > need to understand what the public methods return (not how it works > internally!) ... > > > The second objection is that > > doing all this initialization takes a lot of lines of code and is a tiring > > process. > > > > maybe true ... will need an example though to prove it... > > > Now, would it be easier with Cactus ? I think so ... for the following > > reasons. > > Here is how you would do it with Cactus : > > > > ActionServlet servlet = new ActionServlet(); > > servlet.init(config); > > > > this is true! MO cannot beat this ... > > > (you'll also have to provide a struts-config.xml file but that's fine as > you > > have to write one for Struts anyway). > > that's all, Struts is initialized ! You don't need to understand how > struts > > works internally. Of course, you could do the same with Mock Objects but > > you'll no longer be following the Mock Objects principles. > > > > Conclusion > > ----------- > > > > Mock Objects has limitations in the following areas : > > - when the API to mock is not yours and especially if you don't have > access > > to the source code because :; > > - it takes time to understand how the API works internally > > no! > > > - it takes time for every test to initialize the API environment > properly. > > maybe > > > - it is difficult when your class to test is using an Application (as > > opposed to a framework). A framework is for exemple a logging framework, > it > > contains no state and no business logic, so it is easy to mock. However a > > framework like Struts is actually an Application : it has state and it has > > logic, thus you need to understand its internal functioning to mock it. > > not completely sure it is wrong, maybe there is some truth in that... > > > > > I would very much like to have you thoughts on that, especially if you > don't > > agree ! :) > > please don't flame me ... :) > > > Thanks > > > > -Vincent > > > > > > |
From: Thomas C. <ald...@ne...> - 2001-08-08 15:28:14
|
Vincent "The getLocale() method is actually implemented in the Action class ... So I can see 2 ways of coping with this : * Solution 1: Create a LogonActionForTest class that extends LogonAction and override the getLocale() method so that it returns what we want," If I am following this thread correctly, I think it is useful to consider that, although the article I posted earlier shows how to override methods of objects passed in *as parameters*, the same technique is useful in overriding methods of the actual test subject during testing, as I think you are realizing in terms of overriding the getLocale() method. At first, it feels like a violation of the normative Heisenberg uncertainty principle because you are *changing the class you are testing*, but unit testing is concerned with particular *methods*, not classes. Therefore, as long as you do not override the method you are testing with the anonymous inner class, you can actually use an anonymous inner class to redefine an object you are about to test, including any methods except the one you are testing. I can provide a code example if necessary (I need to write one for the article anyway). Tom |
From: Vincent M. <vm...@oc...> - 2001-08-08 15:43:30
|
----- Original Message ----- From: "Thomas Calivera" <ald...@ne...> To: <moc...@li...>; <cac...@ja...> Sent: Wednesday, August 08, 2001 4:26 PM Subject: Re: [Mockobjects-java-users] Advantage for In-Container vs Mock ? > Vincent > > "The getLocale() method is actually implemented in the Action class ... So I > can see 2 ways of coping with this : > * Solution 1: Create a LogonActionForTest class that extends LogonAction and > override the getLocale() method so that it returns what we want," > > If I am following this thread correctly, I think it is useful to consider > that, although the article I posted earlier shows how to override methods of > objects passed in *as parameters*, the same technique is useful in > overriding methods of the actual test subject during testing, as I think you > are realizing in terms of overriding the getLocale() method. > yep > At first, it feels like a violation of the normative Heisenberg uncertainty fancy name ! I am now wiser than before ... :) > principle because you are *changing the class you are testing*, but unit > testing is concerned with particular *methods*, not classes. Therefore, as > long as you do not override the method you are testing with the anonymous > inner class, you can actually use an anonymous inner class to redefine an > object you are about to test, including any methods except the one you are > testing. I can provide a code example if necessary (I need to write one for > the article anyway). I'm still not convinced of the advantage of these inner classes of yours ... I don't see what advanatges it brings ... Because anyway you need an implementation of the mock (be it static or dynamic). Now what remains is to define your expectation on the mock object and this is easily done by use method calls to setExpectedXXX()-like methods. Something I am missing ? > > Tom -Vincent |
From: Thomas C. <ald...@ne...> - 2001-08-09 18:42:06
|
Vincent "fancy name ! I am now wiser than before ... :)" Upon rereading that, I can only conclude that my inner academic made a stealthy strike before the send command. :) "I'm still not convinced of the advantage of these inner classes of yours ... I don't see what advanatges it brings ... Because anyway you need an implementation of the mock (be it static or dynamic). Now what remains is to define your expectation on the mock object and this is easily done by use method calls to setExpectedXXX()-like methods. Something I am missing ?" With a proxy, you generally only need to mock a couple specific methods rather than the whole interface. If an interface does not exist, then what are you going to do without inner classes to mock specific methods an implementation class? If you have the chance, I would like to see some code that allows for the setExpectedXXX() methods you are referring to. Is it in the mock object source that I have on hand? Do you have to write a special mock class for an interface to track methods calls and parameters? If so, let's reverse the question and ask why write a library to set and test expectations when it is easily done by using features of the platform itself? Also, I don't want to get into too much detail until I get some feedback about the last version of the article I posted here, but the use of inner classes that set outer class variables makes the use of the Verifiable interface unnecessary in many cases. Furthermore, when you are testing the method of a particular class, you can override other methods of that same class to check expectations on inter-class calls. Tom |
From: Vincent M. <vm...@oc...> - 2001-08-10 09:57:42
|
----- Original Message ----- From: "Thomas Calivera" <ald...@ne...> To: <moc...@li...>; <cac...@ja...> Sent: Thursday, August 09, 2001 7:23 PM Subject: Re: [Mockobjects-java-users] Advantage for In-Container vs Mock ? > Vincent > > "fancy name ! I am now wiser than before ... :)" > > Upon rereading that, I can only conclude that my inner academic made a > stealthy strike before the send command. :) > > "I'm still not convinced of the advantage of these inner classes of yours > ... > I don't see what advanatges it brings ... Because anyway you need an > implementation of the mock (be it static or dynamic). Now what remains is to > define your expectation on the mock object and this is easily done by use > method calls to setExpectedXXX()-like methods. Something I am missing ?" > > With a proxy, you generally only need to mock a couple specific methods > rather than the whole interface. If an interface does not exist, then what > are you going to do without inner classes to mock specific methods an > implementation class? I like the dynamic proxy because it enables to skip the static mock implementation generation step. Even if you don't have an interface you can still extend a class. The idea that the Mock Objects has been developing is that the actual mock implementation could be generated because they do not contain any logic code. For example, for each method XXX in the interface of class to mock, a generation process could produce the following methods : MockYYY.java setActualValueXXX() setExpectedValueXXX() setActualExceptionXXX() XXX() And it can generate a verify() method for each mock class which will check all setExpected*() methods. so that it is up to the writer of the test case to say what he expects of the call to XXX(), as in : public void testSomething() { MockYYY mock = new MockYYY(); mock.setActualValueXXX("text/html"); mock.setActualValueZZZ(true); ... // set the expectations on the mock object (if need be) mock.setExpectedValueAAA("something"); ... // the method to unit test that calls XXX // and ZZZ as part of it's logic String result = myObject.someMethod(); ... // then the asserts, which can be a mix of junit asserts and // verifying against the expectations set on the mock object assertEquals("...", result); mock.verify(); } Now, the only questions which is not 100% answered (at least for what I know) is : Is that mechanism going to work in 100% of cases or are there cases where it won't work. I'm still looking for counter examples. But I have not put it in practice either .... I need to use MO to understand better what would be the limitations if any ... We probably need to work on a real life example and see how it's unit tests are addressed by MO and Cactus. I have a project in mind that would be a perfect live example for that. I'll make a proposition shortly on both Cactus and MO lists on the subject. > > If you have the chance, I would like to see some code that allows for the > setExpectedXXX() methods you are referring to. Is it in the mock object > source that I have on hand? Do you have to write a special mock class for an > interface to track methods calls and parameters? If so, let's reverse the > question and ask why write a library to set and test expectations when it is > easily done by using features of the platform itself? > The idea is simply that with the above described generic mechanism there is no need to inner classes at all. But I may be wrong and I'd like to know the counter arguments! > Also, I don't want to get into too much detail until I get some feedback > about the last version of the article I posted here, but the use of inner > classes that set outer class variables makes the use of the Verifiable > interface unnecessary in many cases. Furthermore, when you are testing the > method of a particular class, you can override other methods of that same > class to check expectations on inter-class calls. > > Tom -Vincent |
From: Steve F. <st...@m3...> - 2001-08-08 21:49:53
|
PiBUaGUgZ2V0TG9jYWxlKCkgbWV0aG9kIGlzIGFjdHVhbGx5IGltcGxlbWVudGVkIGluIHRoZSBB Y3Rpb24gY2xhc3MgLi4uIFNvIEkNCj4gY2FuIHNlZSAyIHdheXMgb2YgY29waW5nIHdpdGggdGhp cyA6DQo+ICogU29sdXRpb24gMTogQ3JlYXRlIGEgTG9nb25BY3Rpb25Gb3JUZXN0IGNsYXNzIHRo YXQgZXh0ZW5kcyBMb2dvbkFjdGlvbiBhbmQNCj4gb3ZlcnJpZGUgdGhlIGdldExvY2FsZSgpIG1l dGhvZCBzbyB0aGF0IGl0IHJldHVybnMgd2hhdCB3ZSB3YW50LA0KDQp0aGUgcG9pbnQgaGVyZSBp cyB0aGF0IHlvdSdyZSBub3QgdGVzdGluZyB0aGUgTG9nb25BY3Rpb24gY2xhc3MsIG9ubHkgaXRz IGNsaWVudHMuIE15IGluY2xpbmF0aW9uIHdvdWxkIGJlIHRvIG92ZXJyaWRlIF9ldmVyeXRoaW5n XyBpbiBMb2dvbkFjdGlvbiB3aXRoIGR1bWIgbW9jayBtZXRob2RzLiBUaGF0IHdheSB5b3UncmUg bm90IHJlbHlpbmcgb24gYW55IG15c3RlcmlvdXMgYmVoYXZpb3VyIG9mIHRoZSBwYXJlbnQuIA0K DQpXZSd2ZSBkb25lIHRoaXMgZm9yIG1vY2tpbmcgdXAgRHluYW1vIGNsYXNzZXMuDQoNCnN0ZXZl DQoNCg== |
From: Vincent M. <vm...@oc...> - 2001-08-09 06:50:19
|
----- Original Message ----- From: "Steve Freeman" <st...@m3...> To: <moc...@li...> Sent: Wednesday, August 08, 2001 10:21 PM Subject: Re: [Mockobjects-java-users] Advantage for In-Container vs Mock ? > > The getLocale() method is actually implemented in the Action class ... So I > > can see 2 ways of coping with this : > > * Solution 1: Create a LogonActionForTest class that extends LogonAction and > > override the getLocale() method so that it returns what we want, > > the point here is that you're not testing the LogonAction class, only its clients. My inclination would be to override _everything_ in LogonAction with dumb mock methods. That way you're not relying on any mysterious behaviour of the parent. > > We've done this for mocking up Dynamo classes. er ... what do I test then ? :) No, I think there is misunderstanding: what I am unit testing is the LogonAction class itself, which is why I cannot mock it ... The class that we are not testing is the Action class but we cannot override it as the LogonAction is extending it. The only way is by extending the LogonAction class and override the methods that are implemented in Action and _not_ in LogonAction, which is what solution 1 is about. > > steve -Vincent |
From: Vincent M. <vm...@oc...> - 2001-08-21 17:10:05
|
Can I modify the directory structure to be : src |_ core |_ java |_ com/mockobjects/[...] |_ tests |_ com/mockobjects/[...] |_ examples |_ com/mockobjects/examples/[...] The core only contains the core classes (expectation lists, ...) and is useful for projects like Mock Maker and others that do not need the mock implementations. The distributable will be "mockobjects-java-core.jar" |_ standard (or a better name) |_ java |_ tests |_ examples For the sub directories under the java directory, we have several choices : choice 1 : use the same package as the classes to mock. For example, the mock for HttpURLConnection will be in the java.net package. the mock for HttpServletRequest will be in javax.servlet.http, ... There is little risk that there will a name collision (as we name our classes MockXXX, but it still exists) choice 2 : use the java hierarchy but prefix by our domain name. For example, MockHttpServletRequest will be in the com.mockobjects.javax.servlet.http package choice 3: keep the existing packages, i.e. no rules. MockHttpServletRequest will be in com.mockobjects.servlet The "standard " directory will provides mock implementations for the java platform (java.* and javax.* packages). The distributable will be "mockobjects-java-standard.jar" |_ extensions |_ atg |_ java |_ tests |_ examples |_ ... Each extension will be delivered as a separate jar. For example the atg mocks will be delivered as : "mockobjects-java-atg.jar" Any comment ? I'd like to do that ASAP ... so please hurry to comment if you don't agree ... :) Thanks -Vincent |
From: Steve F. <st...@m3...> - 2001-08-22 22:15:50
|
RnJvbTogIlZpbmNlbnQgTWFzc29sIiA8dm1hc3NvbEBvY3RvLmNvbT4NCj4gQ2FuIEkgbW9kaWZ5 IHRoZSBkaXJlY3Rvcnkgc3RydWN0dXJlIHRvIGJlIDoNCj4gDQo+IHNyYw0KPiAgIHxfIGNvcmUN Cj4gICAgIHxfIGphdmENCj4gICAgICAgfF8gY29tL21vY2tvYmplY3RzL1suLi5dDQo+ICAgICB8 XyB0ZXN0cw0KPiAgICAgICB8XyBjb20vbW9ja29iamVjdHMvWy4uLl0NCj4gICAgIHxfIGV4YW1w bGVzDQo+ICAgICAgIHxfIGNvbS9tb2Nrb2JqZWN0cy9leGFtcGxlcy9bLi4uXQ0KPiANCj4gVGhl IGNvcmUgb25seSBjb250YWlucyB0aGUgY29yZSBjbGFzc2VzIChleHBlY3RhdGlvbiBsaXN0cywg Li4uKSBhbmQgaXMNCj4gdXNlZnVsIGZvciBwcm9qZWN0cyBsaWtlIE1vY2sgTWFrZXIgYW5kIG90 aGVycyB0aGF0IGRvIG5vdCBuZWVkIHRoZSBtb2NrDQo+IGltcGxlbWVudGF0aW9ucy4gVGhlIGRp c3RyaWJ1dGFibGUgd2lsbCBiZSAibW9ja29iamVjdHMtamF2YS1jb3JlLmphciINCg0KdXNlICdz cmMnIGluc3RlYWQgb2YgJ2phdmEnLiBJdCdzIGFsbCBqYXZhLg0KDQpkb24ndCBmb3JnZXQgdXRp bC4gVGhpcyBsaWJyYXJ5IGlzIHVubGlrZWx5IHRvIGluY2x1ZGUgZXhhbXBsZXMgYXMgdGhlIHVu aXQgdGVzdHMgd2lsbCBjb3ZlciB0aGF0LiANCg0KPiAgIHxfIHN0YW5kYXJkIChvciBhIGJldHRl ciBuYW1lKQ0KPiAgICAgfF8gamF2YQ0KPiAgICAgfF8gdGVzdHMNCj4gICAgIHxfIGV4YW1wbGVz DQo+IEZvciB0aGUgc3ViIGRpcmVjdG9yaWVzIHVuZGVyIHRoZSBqYXZhIGRpcmVjdG9yeSwgd2Ug aGF2ZSBzZXZlcmFsIGNob2ljZXMgOg0KDQo+IGNob2ljZSAxIDogdXNlIHRoZSBzYW1lIHBhY2th Z2UgYXMgdGhlIGNsYXNzZXMgdG8gbW9jay4gRm9yIGV4YW1wbGUsIHRoZQ0KPiBtb2NrIGZvciBI dHRwVVJMQ29ubmVjdGlvbiB3aWxsIGJlIGluIHRoZSBqYXZhLm5ldCBwYWNrYWdlLiB0aGUgbW9j ayBmb3INCj4gSHR0cFNlcnZsZXRSZXF1ZXN0IHdpbGwgYmUgaW4gamF2YXguc2VydmxldC5odHRw LCAuLi4gVGhlcmUgaXMgbGl0dGxlIHJpc2sNCj4gdGhhdCB0aGVyZSB3aWxsIGEgbmFtZSBjb2xs aXNpb24gKGFzIHdlIG5hbWUgb3VyIGNsYXNzZXMgTW9ja1hYWCwgYnV0IGl0DQo+IHN0aWxsIGV4 aXN0cykNCg0KY2FuJ3QgZG8gdGhhdC4gY2xhc2hlcyB3aXRoIFZpc3VhbEFnZS4NCg0KPiBjaG9p Y2UgMiA6IHVzZSB0aGUgamF2YSBoaWVyYXJjaHkgYnV0IHByZWZpeCBieSBvdXIgZG9tYWluIG5h bWUuIEZvcg0KPiBleGFtcGxlLCBNb2NrSHR0cFNlcnZsZXRSZXF1ZXN0IHdpbGwgYmUgaW4gdGhl DQo+IGNvbS5tb2Nrb2JqZWN0cy5qYXZheC5zZXJ2bGV0Lmh0dHAgcGFja2FnZQ0KDQp0b28gbG9u Zw0KIA0KPiBjaG9pY2UgMzoga2VlcCB0aGUgZXhpc3RpbmcgcGFja2FnZXMsIGkuZS4gbm8gcnVs ZXMuIE1vY2tIdHRwU2VydmxldFJlcXVlc3QNCj4gd2lsbCBiZSBpbiBjb20ubW9ja29iamVjdHMu c2VydmxldA0KDQpBY3R1YWxseSwgdGhpcyBzZWVtcyB0byB3b3JrIHF1aXRlIHdlbGwgYXMgd2Ug dGVuZCB0byBtb2NrIHVwIG9ubHkgYSBzdWJzZXQgb2YgdGhlIHR5cGVzIGZyb20gZWFjaCBsaWJy YXJ5LCBhbmQgaXQgbWFrZXMgdGhlIGxvY2F0aW9ucyByZWFsbHkgb2J2aW91cy4gQWxzbywgaXQg YXZvaWRzIGV4Y2Vzc2l2ZSBpbXBvcnRzIGludG8gdGVzdCBjbGFzc2VzLg0KDQpBbiBhbHRlcm5h dGl2ZSBtaWdodCBiZSBtb2NrLnNxbC4qOyBtb2NrLmlibS50aGlzLnRoYXQuKg0KDQo+IFRoZSAi c3RhbmRhcmQgIiBkaXJlY3Rvcnkgd2lsbCBwcm92aWRlcyBtb2NrIGltcGxlbWVudGF0aW9ucyBm b3IgdGhlIGphdmENCj4gcGxhdGZvcm0gKGphdmEuKiBhbmQgamF2YXguKiBwYWNrYWdlcykuIFRo ZSBkaXN0cmlidXRhYmxlIHdpbGwgYmUNCj4gIm1vY2tvYmplY3RzLWphdmEtc3RhbmRhcmQuamFy Ig0KDQpJIHdvdWxkIGluY2x1ZGUgdGhlIGNvcmUgY2xhc3NlcyBpbiB0aGlzIGphciB0byBhdm9p ZCBleGNlc3NpdmUgY2xhc3NwYXRocywgYW5kIG5vdCBpbmNsdWRlIHRoZSB0ZXN0cyBvciBleGFt cGxlcy4gDQogDQo+ICAgfF8gZXh0ZW5zaW9ucw0KPiAgICAgfF8gYXRnDQo+ICAgICAgIHxfIGph dmENCj4gICAgICAgfF8gdGVzdHMNCj4gICAgICAgfF8gZXhhbXBsZXMNCj4gICAgIHxfIC4uLg0K PiANCj4gRWFjaCBleHRlbnNpb24gd2lsbCBiZSBkZWxpdmVyZWQgYXMgYSBzZXBhcmF0ZSBqYXIu IEZvciBleGFtcGxlIHRoZSBhdGcNCj4gbW9ja3Mgd2lsbCBiZSBkZWxpdmVyZWQgYXMgOiAibW9j a29iamVjdHMtamF2YS1hdGcuamFyIg0KDQpXZSBtaWdodCB3YW50IGp1c3QgdG8gZGVsaXZlciB0 aGUgc291cmNlIGNvZGUuIFdlIGNhbid0IGNvbXBpbGUgdGhlc2Ugd2l0aG91dCB0aGUgdmFyaW91 cyAzcmQgcGFydHkgbGlicmFyaWVzIGFuZCBpdCBjb3VsZCBhbGwgZ2V0IHZlcnkgY29tcGxpY2F0 ZWQuDQoNCj4gSSdkIGxpa2UgdG8gZG8gdGhhdCBBU0FQIC4uLiBzbyBwbGVhc2UgaHVycnkgdG8g Y29tbWVudCBpZiB5b3UgZG9uJ3QgYWdyZWUNCg0KSWYgeW91J3JlIGdvaW5nIHRvIG1ha2UgY2hh bmdlcyB0aGF0IHB1dCB0aGUgY29ubmV4dHJhIGNvZGViYXNlIGF0IHJpc2ssIHdlJ2QgYmV0dGVy IHN0aWNrIHRvIHRoZSBjdXJyZW50IHBhY2thZ2luZyAtLSB1bmxlc3MgeW91IGNhbiBnZXQgYWdy ZWVtZW50IGZyb20gVGltLg0KDQoNCg== |
From: Vincent M. <vm...@oc...> - 2001-08-23 06:41:14
|
----- Original Message ----- From: "Steve Freeman" <st...@m3...> To: <moc...@li...> Sent: Wednesday, August 22, 2001 11:14 PM Subject: Re: [Mockobjects-java-users] Directory structure > From: "Vincent Massol" <vm...@oc...> > > Can I modify the directory structure to be : > > > > src > > |_ core > > |_ java > > |_ com/mockobjects/[...] > > |_ tests > > |_ com/mockobjects/[...] > > |_ examples > > |_ com/mockobjects/examples/[...] > > > > The core only contains the core classes (expectation lists, ...) and is > > useful for projects like Mock Maker and others that do not need the mock > > implementations. The distributable will be "mockobjects-java-core.jar" > > use 'src' instead of 'java'. It's all java. yes, sure but there is already a src directory ... I am actually not inventing here, just using a standard convention that I have seen all over the place in open source java land. > > don't forget util. This library is unlikely to include examples as the unit tests will cover that. util is in java/com/mockobjects/util, right ? > > > |_ standard (or a better name) > > |_ java > > |_ tests > > |_ examples > > For the sub directories under the java directory, we have several choices : > > > choice 1 : use the same package as the classes to mock. For example, the > > mock for HttpURLConnection will be in the java.net package. the mock for > > HttpServletRequest will be in javax.servlet.http, ... There is little risk > > that there will a name collision (as we name our classes MockXXX, but it > > still exists) > > can't do that. clashes with VisualAge. :( > > > choice 2 : use the java hierarchy but prefix by our domain name. For > > example, MockHttpServletRequest will be in the > > com.mockobjects.javax.servlet.http package > > too long yes, I agree, but consistent and give us room ... > > > choice 3: keep the existing packages, i.e. no rules. MockHttpServletRequest > > will be in com.mockobjects.servlet > > Actually, this seems to work quite well as we tend to mock up only a subset of the types from each library, and it makes the locations really obvious. Also, it avoids excessive imports into test classes. ok, we keep this one. We'll address the issue if it becomes one, later ... :) > > An alternative might be mock.sql.*; mock.ibm.this.that.* > > > The "standard " directory will provides mock implementations for the java > > platform (java.* and javax.* packages). The distributable will be > > "mockobjects-java-standard.jar" > > I would include the core classes in this jar to avoid excessive classpaths, and not include the tests or examples. ok, good idea. > > > |_ extensions > > |_ atg > > |_ java > > |_ tests > > |_ examples > > |_ ... > > > > Each extension will be delivered as a separate jar. For example the atg > > mocks will be delivered as : "mockobjects-java-atg.jar" > > We might want just to deliver the source code. We can't compile these without the various 3rd party libraries and it could all get very complicated. ok, agreed, replace .jar by .zip > > > I'd like to do that ASAP ... so please hurry to comment if you don't agree > > If you're going to make changes that put the connextra codebase at risk, we'd better stick to the current packaging -- unless you can get agreement from Tim. As we won't change the package name, it won't put anyone at risk ... -Vincent |
From: Steve F. <st...@m3...> - 2001-08-23 21:44:41
|
PiA+IHVzZSAnc3JjJyBpbnN0ZWFkIG9mICdqYXZhJy4gSXQncyBhbGwgamF2YS4NCj4gDQo+IHll cywgc3VyZSBidXQgdGhlcmUgaXMgYWxyZWFkeSBhIHNyYyBkaXJlY3RvcnkgLi4uIEkgYW0gYWN0 dWFsbHkgbm90DQo+IGludmVudGluZyBoZXJlLCBqdXN0IHVzaW5nIGEgc3RhbmRhcmQgY29udmVu dGlvbiB0aGF0IEkgaGF2ZSBzZWVuIGFsbCBvdmVyDQo+IHRoZSBwbGFjZSBpbiBvcGVuIHNvdXJj ZSBqYXZhIGxhbmQuDQoNCll1ay4gT0sNCg0KPiB1dGlsIGlzIGluIGphdmEvY29tL21vY2tvYmpl Y3RzL3V0aWwsIHJpZ2h0ID8NCg0KeWVzDQoNCj4gb2ssIHdlIGtlZXAgdGhpcyBvbmUuIFdlJ2xs IGFkZHJlc3MgdGhlIGlzc3VlIGlmIGl0IGJlY29tZXMgb25lLCBsYXRlciAuLi4NCj4gOikNCg0K WUFHTkkgIQ0KDQoNCg== |
From: Vincent M. <vm...@oc...> - 2001-09-05 16:35:53
|
Hi, I have a simpe servlet with a doGet() method that simply prints a text to the output stream. I would like to know what is the correct way of writing a unit test for that method. It seems the suggested way (from the Mock Object sample and source code of MockHttpServletResponse) is to write: { SampleServlet servlet = new SampleServlet(); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); servlet.doGet(request, response); String expected = "<h1>A request</h1>"; String result = response.getOutputStreamContents(); assertEquals(expected, result); } However, I don't believe this is the canonical way of writing this test. I think it would be more appropriate and consistent to write (even if longer) : { SampleServlet servlet = new SampleServlet(); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); MockServletOutputStream output = new MockServletOutputStream(); output.setExpectedContent("<h1>A request</h1>"); response.setupOutputStream(output); servlet.doGet(request, response); output.verify(); } Question 1 : What do you think ? Should the example be changed ? Should the MockHttpServletResponse.getOutputStreamContents() method be removed ? Question 2 : Is it possible to automatically generate a mock of ServletOutputStream ? It would certainly not generate a setExpectedContent() method, right ? It would maybe generate a setExpectedWrite() method but that would not represent the full buffer... ServletOutputStream is an object that gets written to by the method under test, which means we need some accessors to get back the data. How can Mock Maker generate these accessors in a generic way ? Thanks -Vincent |
From: Vincent M. <vm...@oc...> - 2001-09-06 08:03:29
|
Steve, I am trying to find out if a generic way of writing mocks is possible and if a tool like MockMaker would be good enough. My question is thus: what would be the algorithm for generating a mock implementation of ServletOutputStream ? Thanks -Vincent ----- Original Message ----- From: "Steve Freeman" <st...@m3...> To: "Vincent Massol" <vm...@oc...> Sent: Wednesday, September 05, 2001 6:28 PM Subject: Re: [Mockobjects-java-users] What is the correct way of writing this test ? > This is example is OK as a very first cut at writing a servlet test. You would expect some kind of intermediate objects start to appear as soon as things became much more complicated. You certainly can't look for expected writes because of potential bufferings in the stream. > > setExpectedContent is not much different for a string than just getting it at the end. One thing I have worked on is a setExpectedSegment, which checks if a particular (small) substring is present. Either way, you should get away from testing strings like this as soon as you can, but you need to start somewhere. > > Steve > > ----- Original Message ----- > From: "Vincent Massol" <vm...@oc...> > To: <moc...@li...> > Sent: Wednesday, September 05, 2001 5:40 PM > Subject: [Mockobjects-java-users] What is the correct way of writing this test ? > > > > Hi, > > > > I have a simpe servlet with a doGet() method that simply prints a text to > > the output stream. I would like to know what is the correct way of writing a > > unit test for that method. It seems the suggested way (from the Mock Object > > sample and source code of MockHttpServletResponse) is to write: > > > > { > > SampleServlet servlet = new SampleServlet(); > > MockHttpServletRequest request = new MockHttpServletRequest(); > > MockHttpServletResponse response = new MockHttpServletResponse(); > > > > servlet.doGet(request, response); > > > > String expected = "<h1>A request</h1>"; > > String result = response.getOutputStreamContents(); > > assertEquals(expected, result); > > } > > > > However, I don't believe this is the canonical way of writing this test. I > > think > > it would be more appropriate and consistent to write (even if longer) : > > > > { > > SampleServlet servlet = new SampleServlet(); > > MockHttpServletRequest request = new MockHttpServletRequest(); > > MockHttpServletResponse response = new MockHttpServletResponse(); > > > > MockServletOutputStream output = new MockServletOutputStream(); > > > > output.setExpectedContent("<h1>A request</h1>"); > > response.setupOutputStream(output); > > > > servlet.doGet(request, response); > > > > output.verify(); > > } > > > > Question 1 : What do you think ? Should the example be changed ? Should the > > MockHttpServletResponse.getOutputStreamContents() method be removed ? > > Question 2 : Is it possible to automatically generate a mock of > > ServletOutputStream ? It would certainly not generate a setExpectedContent() > > method, right ? It would maybe generate a setExpectedWrite() method but that > > would not represent the full buffer... ServletOutputStream is an object > > that gets written to by the method under test, which means we need some > > accessors to get back the data. How can Mock Maker generate these accessors > > in a generic way ? > > > > Thanks > > -Vincent > > > > > > _______________________________________________ > > Mockobjects-java-users mailing list > > Moc...@li... > > https://lists.sourceforge.net/lists/listinfo/mockobjects-java-users > > > |
From: Vincent M. <vm...@oc...> - 2001-09-06 10:25:54
|
----- Original Message ----- From: "Steve Freeman" <st...@m3...> To: "Vincent Massol" <vm...@oc...> Sent: Thursday, September 06, 2001 11:18 AM Subject: Re: [Mockobjects-java-users] What is the correct way of writing this test ? > > I am trying to find out if a generic way of writing mocks is possible and if > > a tool like MockMaker would be good enough. My question is thus: what would > > be the algorithm for generating a mock implementation of ServletOutputStream > > I'm sure that many mocks can be generated automatically, but not all. Unfortunately, output stream is a bad candidate because you shouldn't put too many restrictions on how the write methods are called. So, a stub implmenentation is as good as any and you can mess with the contents after the test. What's more interesting is to move to some kind of intermediate object as soon as possible so that you can put some structure in the code -- at which point a mock makes is more useful. > I'm not sure I agree with "many mocks can be generated automatically" ... I was just trying to convert my Cactus test cases into Mock Objects one to see how the test would differ. I also wanted to use generated mocks to see if it is usable. I started translating the first test ... and hit the ServletOutputStream issue ... I'm not sure I undestand the intermediate object you are referring to. Can you give an example on the test case I have written : { SampleServlet servlet = new SampleServlet(); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); MockServletOutputStream output = new MockServletOutputStream(); output.setExpectedContent("<h1>A request</h1>"); response.setupOutputStream(output); servlet.doGet(request, response); output.verify(); } Thanks -Vincent |