From: Vincent M. <vm...@oc...> - 2001-11-04 22:35:35
|
Hi Vince, I'm copying the list as I think they will find this question of = interest. ----- Original Message -----=20 From: Vincent Tenc=E9=20 To: Vincent Massol=20 Sent: Thursday, November 01, 2001 12:22 AM Subject: Re: [Mockobjects-java-dev] Interested in participating No pb. I myself have a lot of things to do at the moment. The project = is entering in its final phase and the next month will be pretty crazy. = I am afraid I wont have a lot of free time. We want to develop lots of = mock objects for our domain classes and service classes and rewrite our = tests using them.=20 use cactus, you don't need to write mocks ... No, I'm just teasing ... ! = :) A quick question. We are always facing the same issue and I would like = to know what is the approach you would recommend. The question is, how = do we substitute our domain objects for mock implementations at runtime = ? Here is what we do currently: 1) We define our domain/service objects in terms of abstract classes = or preferably interfaces 2) We add a Facade (for domain packages or service packages for = instance) or a Factory (i.e. for DAOs) to create or access instances of = objects 3) We have a kind of JNDI registry that we lookup at runtime for = components by role (like a specific service provider), roles are defined = in terms of interfaces We can then setup our tests by binding to the registry mock = implementations of specific components (roles) and our code under test = looks the registry up and gets mock objects. I suppose you have faced = this pb before. What was your approach ? What I don't like too much witht this approach is that for testing = consideration, you're going to suffer performance penalties and = implement something more complex than it should be (I may not be = understanding correctly what you said) : - each call from one class to another will have to go through JNDI, = instead of the standard intra JVM method to method call. Yes, you can = improve the performance a bit by providing a facade/factory that would = cache the objects but then you'll need to provide your own garbage = collection mechanism ... What you are doing in effect is replacing the = inter-class communication mechanism by providing a loosely coupled one. = This can be a good architecture *but* at the component level and = certainly not at the class level where you'll suffer horrible = performances ... What are the other options ? Answer : good design. A good design will = try to minimise dependencies between classes. One solution is the IOC = (inversion of control) pattern. In summary it says that instead of = having your class instanciate some domain objects, they are passed to = it. For example, let's imagine that your class to test need to connect to a = database. A first implementation could be : Implementation 1: public class MyClass { public void doSomething() { // some JDBC code } } second implementation: you factor the code using the JDBC API in a = JDBCWrapper class (or better yet, in a JDBCDataAccessService class, = implementing a DataAccessService interface). Now, your doSomething() = method does not use JDBC but rather the DataAccessService class : Implementation 2: public class MyClass { public void doSomething() { DataAccess dataService =3D new JDBCDataAccess(); // code that uses dataService } } This is better but not enough to be able to unit test MyClass. What we = need is the possibility to replace JDBCDataAccess by a mock = implementation. Instead of creating the object in doSomething(), you're = going to let the caller pass the implementation to MyClass ... The = result: your MyClass is now more generic and able to work with JDBC, = with an OODB, with flat files, ... and with mocks ... Implementation 3: public class MyClass { private DataAccessService service; public void setDataAccessService(DataAccessService service) { this.service =3D service; } public void doSomething() { // codde that uses this.service } } Note: if you want to be sure that setDataAccessService has been called, = put it as a parameter of your constructor (or of the doSomething() = method). Now, your unit test : public void testDoSomething() { // init MockDataAccessService service =3D new MockDataAccessService(); MyClass class =3D new MyClass(); class.setDataAccessService(service); =20 // test class.doSomething(); // verify assertEquals( .....); } -Vincent PS: I hope I have understood your question ! Thanks, Vincent ----- Original Message -----=20 From: Vincent Massol=20 To: Vincent Tenc=E9=20 Sent: Wednesday, October 31, 2001 6:49 PM Subject: Re: [Mockobjects-java-dev] Interested in participating Vince, I just realized I have not answered to you. Sorry about that = ! can you wait 2 more days ... will do that this coming week end (It = needs to thinking ... :) ). thanks cheers, -Vincent -- Vincent Massol, vm...@oc... OCTO Technology, www.octo.com Information System Architecture Consulting ----- Original Message -----=20 From: Vincent Tenc=E9=20 To: Vincent Massol=20 Cc: vin...@ge...=20 Sent: Monday, October 22, 2001 2:20 AM Subject: Re: [Mockobjects-java-dev] Interested in participating Hi Vince, It's interesting to discuss the pros and cons of MockObjects vs = in-container testing. We are using Catcus a part of our test strategy = and we had some debates ourselves at the beginning on what was the best = approach to use. We quickly realised though that both approaches were = complementary. When the project began, the domain code was still rather simple = and running tests was not an issue. But as soon as we added mor elogic = (domain, crypto) and we started interfacing with external systems (DBs, = JMS providers), we notices that running tests took longer and longer. = We had to develop simulators for external systems, create tests data for = databases and back-end systems accessed through JMS as well as encrypted = incoming data that would go through our cypto libs. It was rather = frustating to see that frequently our domain code was bug-free but our = simulators or data were corrupted. We measured that 2 times out of 3 = tests failures were not due to our domain code. Worst, we had to fix the = bugs before going on and we found it 2 to 3 times longer fixing those = bugs simply because we had no tests to back up our simulators or test = data! I didnt express myself correctly saying that we encountered = limitations with our in-container testing strategy. It was rather our = test strategy as a whole that proved to be poor. Mock objects solved a = lot of our problems with its capacity to do really fine grained unit = tests. We rewrote some of the critical tests that caused problems (DBs, = JMS, Crypto) and now those tests run correclty 100% of the time. We = still use Cactus, but at a much higher level, to test our use cases. So = its like integration tests on a use case by use case basis. To focus on the discussion Mock vs In-container, in our opinion = one of the big advantage of mock objects is the capacity to write very = focused unit tests and sometimes testing pieces of code it would be = difficult to test otherwise. The tests can run very quickly and = independently (most of the time) of external settings ensuring that once = they have passed, we dont have to worry about them anymore. A side = effect of using mock objects was that we ended up writing better code, = thought more in terns of interfaces, removing unecessary dependencies = between domain objects and singletons for instance. On the other hand, using mo proved to be challenging and it still = is. It took time to understand and use them properly, then it took time = to write our own properly (respecting the concepts). We also had to = change parts of our code to introduce the mock objects, adding factories = and registry so that domain objects implementations can be replaced by = mock objects implementations during testing. But once they are written, = like tests, we can leverage mo on subsequent projects. I would imagine that If you participate in both Catcus and MO, you = also feel that both approaches are complementary :-) I will be very busy in the next weeks or so on my project, but I = can still spare some free time to help on the project. Let me think of = the best way for me to help. Regards, Vincent ----- Original Message -----=20 From: Vincent Massol=20 To: Vincent Tenc=E9 ; moc...@li... = Sent: Thursday, October 18, 2001 4:36 AM Subject: Re: [Mockobjects-java-dev] Interested in participating Hi Vince, ----- Original Message -----=20 From: Vincent Tenc=E9=20 To: moc...@li...=20 Sent: Thursday, October 18, 2001 3:36 AM Subject: [Mockobjects-java-dev] Interested in participating Hi all, First of all thanks for the framework, it is of unvaluable = use. Great work.=20 thanks :) We have been developping servlets and were doing in-container = testing up to recently. The limitations that we encountered forced us to = look for a different testing=20 I would be interested in hearing these as I'm participating to = both Cactus (in-container testing) and Mock Objects. I have my own ideas = on the pros and cons of each but would be very interested to hear from = someone who has really used both approaches, on a real project. approach until we read about mock objects. We used the mock = objects servlet package, extended it for our own use, measured the = benefits then decided to develop a mock objects JMS package (it works = fine and serves us well). Now we plan to convert all our DAO unit tests = to using mock objects. Like with JUnit tests, since we tried mock objects, we have a = hard time doing our tests any different way. So if you guys would accept = some help we would be pleased to participate in the effort, being = addicted mock objects users ourselves! that's really great to hear ! :o) Welcome aboard. I fear we = haven't had as much time as we would like so far and any help is = welcome. Have a look at CVS and choose what you'd like to do. = Unfortunately we've not made a todo list yet. Maybe you could propose = items for the todo list and volunteer for some of them ? These are the = different areas where you could help : - improve existing code and especially code that is not = finished. The servlet mocks for example are far from being finished. - improve build process - improve web site documentation - help answer to mailing-lists posts - promote mock objects around you (I'm sure you're already doing = that !) - anything else you might think of Regards, Vincent Tenc=E9 -Vincent -- Vincent Massol, vm...@oc... OCTO Technology, www.octo.com Information System Architecture Consulting |