At line 10 changed 1 line. |
* Una clase [JUnit|http://www.junit.org] para testear que nuestro DAO funciona :-) |
* Una clase [JUnit|http://www.junit.org] para testear que nuestro DAO funciona :-) |
At line 205 changed 1 line. |
El código anterior es lo que Ud. necesita para realizar una prueba unitaria básica que inicialize y destruya nuestro PersonDao. El objeto "ctx" es una referencia al objeto Application Context de Spring, el cual es inicializado en un bloque estático de la clase [BaseDaoTestCase's|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDaoTestCase.java.html] . |
El código anterior es lo que Ud. necesita para realizar una prueba unitaria básica que inicialize y destruya nuestro PersonDao. El objeto "ctx" es una referencia al objeto Application Context de Spring, el cual es inicializado en un bloque estático de la clase [BaseDaoTestCase's|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDaoTestCase.java.html] . |
At line 207 changed 1 line. |
Ahora necesitamos probar que las operaciones CRUD (create, retrieve, update, delete) methods funcionan en nuestro DAO. Para ello, crearemos metodos que empiecen con el vocablo "test" (en minúsculas). Estos métodos al ser públicos,retornan void y no aceptan parámetros de entrada, serán ejecutados por la tarea <junit> que se encuentra en el fichero build.xml de Ant . |
Ahora necesitamos probar que las operaciones CRUD (create, retrieve, update, delete) methods funcionan en nuestro DAO. Para ello, crearemos metodos que empiecen con el vocablo "test" (en minúsculas). Estos mét;odos al ser públicos,retornan void y no aceptan parámetros de entrada, serán ejecutados por la tarea <junit> que se encuentra en el fichero build.xml de Ant . |
At line 209 changed 2 lines. |
Aca le mostramos algunas pruebas sencillas para probar las operaciones CRUD. Lo importante a recordad es que cada método debe ser autónomo. Anada los siguientes metodos a la clase |
PersonDaoTest.java: |
Aca le mostramos algunas pruebas sencillas para probar las operaciones CRUD. Lo importante a recordad es que cada método debe ser autónomo. Añada los siguientes métodos a la clase PersonDaoTest.java: |
At line 259 changed 1 line. |
;:%%(color: blue)''En el método testGetPerson , estamos creando una persona y luego lo recuperamos de la base de datos. Generalmente adiciono métodos en la base de datos de manera que puedo siempre contar con datos fiables. Debido que [DBUnit|http://www.dbunit.org] es usado para llenar la base de datos con datos para prueba, Ud. puede simplemente anadir una nueva tabla o un record al fichero metadata/sql/sample-data.xml:''%% |
;:%%(color: blue)''En el método testGetPerson , estamos creando una persona y luego lo recuperamos de la base de datos. Generalmente adiciono métodos en la base de datos de manera que puedo siempre contar con datos fiables. Debido que [DBUnit|http://www.dbunit.org] es usado para llenar la base de datos con datos para prueba, Ud. puede simplemente añadir una nueva tabla o un record al fichero metadata/sql/sample-data.xml:''%% |
At line 276 changed 1 line. |
;:%%(color: blue)''De esta manera,puedes eliminar la funcionalidad "create new" en el método testGetPerson. Si prefiere anadir este record directamente a la base de datos , (via SQL o una intefaz GUI), you can rebuild your sample-data.xml file using "ant db-export" and then "cp db-export.xml metadata/sql/sample-data.xml".''%% |
;:%%(color: blue)''De esta manera,puedes eliminar la funcionalidad "create new" en el método testGetPerson. Si prefiere añadir este record directamente a la base de datos , (via SQL o una intefaz GUI), puede reconstruir el fichero sample-data.xml usando "ant db-export" y luego "cp db-export.xml metadata/sql/sample-data.xml".''%% |
At line 278 changed 2 lines. |
In the above example, you can see that we're calling person.set*(value) to populate our object before saving it. This is easy in this example, but it could get quite cumbersome if we're persisting an object with 10 required fields (not-null="true"). This is why I created the ResourceBundle in the BaseDaoTestCase. Simply create a PersonDaoTest.properties file in the same directory as the PersonDaoTest.java file and define your property values inside it: |
;:''I tend to just hard-code test values into Java code - but the .properties file is an option.'' |
En el ejemplo anterior, Ud. puede que estamos invocando los métodos person.set*(valor) para llenar el objeto antes de guardarlo en la base de datos. Es fácil en este ejemplo , pero puede ser un poco enredoso si queremos persistir un objeto con 10 atributos que sean obligatorios (not-null="true"). Es por esta razon que he creado un ResourceBundle en la clase BaseDaoTestCase. Crea simplemente un fichero PersonDaoTest.properties en el mismo directorio que el fichero PersonDaoTest.java y defina los valores de los atributos: |
;:''Normalmente tiendo a definir valores fijos en el código Java - pero el fichero .properties es una opción.'' |
At line 284 removed 1 line. |
Then, rather than calling person.set* to populate your objects, you can use the BaseDaoTestCase.populate(java.lang.Object) method: |
At line 284 added 2 lines. |
Entonces, en vez de invocar los metodos person.set* para poblar los objetos, puede usar el método BaseDaoTestCase.populate(java.lang.Object) : |
|
At line 292 changed 1 line. |
At this point, the PersonDaoTest class won't compile yet because there is no PersonDao.class in our classpath, we need to create it. PersonDAO.java is an interface, and PersonDAOHibernate.java is the Hibernate implementation of that interface. Let's go ahead and create those. |
En este momento, la clase PersonDaoTest class no compilará todavia porque no hay ninguna PersonDao.class en el classpath, por lo tanto tenemos que crearlo. PersonDao.java es una interface y la clase PersonDaoHibernate.java es una implementación de esta interface. |
At line 294 removed 2 lines. |
!!Create a new DAO to perform CRUD on the object [#4] |
First off, create a PersonDao.java interface in the src/dao/**/dao directory and specify the basic CRUD methods for any implementation classes. ''I've eliminated the JavaDocs in the class below for display purposes.'' |
At line 295 added 4 lines. |
!!Crear una nueva clase DAO que contenga métodos CRUD [#4] |
|
Primeramente, creemos la interface PersonDao.java en el directorio src/dao/**/dao y especifique los métodos básicos CRUD. |
|
At line 317 changed 1 line. |
Notice in the class above there are no exceptions on the method signatures. This is due to the power of [Spring|http://www.springframework.org] and how it wraps Exceptions with RuntimeExceptions. At this point, you should be able to compile all the source in src/dao and test/dao using "ant compile-dao". However, if you try to run "ant test-dao -Dtestcase=PersonDao", you will get an error: <span style="color: red">No bean named 'personDao' is defined</span>. This is an error message from Spring - indicating that we need to specify a bean named ''personDAO'' in applicationContext-hibernate.xml. Before we do that, we need to create the PersonDao implementation class. |
Note que en la clase anterior no hay ningún método que provoque excepciones.Esto es debido a la manera que funciona [Spring|http://www.springframework.org] ya que considera las Exceptions como RuntimeExceptions. En este momento, Ud. debe ser capaz de compilar todo el código fuente que se encuentra en src/dao y test/dao usando "ant compile-dao". |
Sin embargo, si trata de ejecutar "ant test-dao -Dtestcase=PersonDao", verá que hay un error: <span style="color: red">No bean named 'personDao' is defined</span>. Este es un mensaje de error de Spring- indicando que necesitamos especificar un bean llamado ''personDAO'' en el fichero applicationContext-hibernate.xml. Antes de hacer esto, necesitamos crear la clase que implementará PersonDao. |
At line 319 changed 1 line. |
;:''The ant task for running dao tests is called "test-dao". If you pass in a testcase parameter (using -Dtestcase=name), it will look for **/*${testcase}* - allowing us to pass in Person, PersonDao, or PersonDaoTest - all of which will execute the PersonDaoTest class.'' |
;:''La tarea ant para ejecutar pruebas dao tests es llamado "test-dao". Si pasa un parámetro (usando -Dtestcase=name), Ant buscará **/*${testcase}* - permitiéndonos pasar Person, PersonDao, o PersonDaoTest - y todas ejecutará la clase PersonDaoTest.'' |
At line 321 changed 1 line. |
Let's start by creating a PersonDaoHibernate class that implements the methods in PersonDao and uses Hibernate to get/save/delete the Person object. To do this, create a new class in src/dao/**/dao/hibernate and name it PersonDAOHibernate.java. It should extend [BaseDaoHibernate|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDAOHibernate.java.html] and implement PersonDAO. ''Javadocs eliminated for brevity.'' |
Empecemos la creación de la clase PeronDAOHibernate que implementa los métodos de la clase PersonDao y usa Hibernate para leer/persistir/eliminar la clase Person. Para ello, cree una nueva clase en el directorio src/dao/**/dao/hibernate bajo el nombre PersonDaoHibernate.java. También debe extender [BaseDaoHibernate|http://raibledesigns.com/downloads/appfuse/api/org/appfuse/dao/BaseDAOHibernate.java.html] e implementar la clase PersonDao. |
At line 360 changed 1 line. |
You'll notice here that we're doing nothing with the ''person'' parameter. This is just a placeholder for now - in the future you may want to filter on it's properties using [Hibernate's Query Language|http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html] (HQL) or using [Criteria Queries|http://www.hibernate.org/hib_docs/reference/en/html/querycriteria.html]. |
Notará que no estamos usando el parámetro ''person''. En You'll notice here that we're doing nothing with the ''person'' parameter. En este momento sirve sólo como variable pero en futuro querrá utilizarla como filtro de sus atributes usando [Hibernate's Query Language|http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html] (HQL) or using [Criteria Queries|http://www.hibernate.org/hib_docs/reference/en/html/querycriteria.html]. |
At line 362 changed 1 line. |
''An example using a Criteria Query:'' |
''Un ejemplo usando el Criteria Query:'' |
At line 380 changed 1 line. |
Now, if you try to run "ant test-dao -Dtestcase=PersonDao", you will get the same error. We need to configure Spring so it knows that PersonDaoHibernate is the implementation of PersonDAO, and we also need to tell it about the Person object. |
Ahora, si quiere ejecutar "ant test-dao -Dtestcase=PersonDao", obtendrá el mismo error. Necesitamos configurar Spring para que sepa que PersonDaoHibernate es una implementación de PersonDao, y también necesitamos indicarle de la existencia de la clase Person. |
At line 382 changed 1 line. |
!!Configure Spring for the Person object and PersonDao [#5] |
!!Configure Spring para la clase Person y PersonDao [#5] |
At line 384 changed 1 line. |
First, we need to tell Spring where the Hibernate mapping file is located. To do this, open src/dao/**/dao/hibernate/applicationContext-hibernate.xml and add {{Person.hbm.xml}} to the following code block. |
Primeramente, necesitamos indicarle a Spring donde se encuentra el fichero de mapeo Hibernate. Para ello, editemos el fichero src/dao/**/dao/hibernate/applicationContext-hibernate.xml y añadimos el fichero {{Person.hbm.xml}} al siguiente bloque. |
At line 392 changed 3 lines. |
<value>org/appfuse/model/User.hbm.xml</value> |
<value>org/appfuse/model/UserCookie.hbm.xml</value> |
<value>org/appfuse/model/UserRole.hbm.xml</value> |
<value>org/appfuse/model/User.hbm.xml</value> |
At line 399 changed 1 line. |
Now we need to add some XML to this file to bind PersonDaoHibernate to PersonDao. To do this, add the following at the bottom of the file: |
Ahora, necesitamos añadir algo de XML a este fichero para enlazar PersonDaoHibernate a PersonDao. Para ello, añadamos lo siguiente al final del fichero: |
At line 409 changed 1 line. |
;:''You could also use __autowire="byName"__ to the <bean> and get rid of the "sessionFactory" property. Personally, I like having the dependencies of my objects documented (in XML).'' |
;:''Podrí también usar __autowire="byName"__ al <bean> y eliminar el atributo "sessionFactory". Personalmente, prefiero documentar las dependencias de los objetos dentro del fichero.'' |
At line 411 changed 2 lines. |
!!Run the DaoTest [#6] |
Save all your edited files and try running "ant test-dao -Dtestcase=PersonDao" one more time. |
!!Ejecute DaoTest [#6] |
Salve los cambios a los ficheros editados y trate de ejecutar "ant test-dao -Dtestcase=PersonDao" . |