Java 测试驱动开发问题

Java 测试驱动开发问题,java,netbeans,jpa,tdd,jakarta-ee,Java,Netbeans,Jpa,Tdd,Jakarta Ee,我是JavaEE6的新手,我正在尝试开发非常简单的JAX-RS应用程序。RESTfull web服务工作正常。然而,当我运行我的测试应用程序时,我得到了以下结果。我做错了什么?还是我忘记了任何配置?当然,我正在创建一个JNDI,并使用Netbeans 6.8 IDE。最后,谢谢你的建议 我的实体: @Entity @Table(name = "BOOK") @NamedQueries({ @NamedQuery(name = "Book.findAll", query = "SELEC

我是JavaEE6的新手,我正在尝试开发非常简单的JAX-RS应用程序。RESTfull web服务工作正常。然而,当我运行我的测试应用程序时,我得到了以下结果。我做错了什么?还是我忘记了任何配置?当然,我正在创建一个JNDI,并使用Netbeans 6.8 IDE。最后,谢谢你的建议

我的实体:


@Entity
@Table(name = "BOOK")
@NamedQueries({
    @NamedQuery(name = "Book.findAll", query = "SELECT b FROM Book b"),
    @NamedQuery(name = "Book.findById", query = "SELECT b FROM Book b WHERE b.id = :id"),
    @NamedQuery(name = "Book.findByTitle", query = "SELECT b FROM Book b WHERE b.title = :title"),
    @NamedQuery(name = "Book.findByDescription", query = "SELECT b FROM Book b WHERE b.description = :description"),
    @NamedQuery(name = "Book.findByPrice", query = "SELECT b FROM Book b WHERE b.price = :price"),
    @NamedQuery(name = "Book.findByNumberofpage", query = "SELECT b FROM Book b WHERE b.numberofpage = :numberofpage")})
public class Book implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "ID")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "TITLE")
    private String title;
    @Basic(optional = false)
    @Column(name = "DESCRIPTION")
    private String description;
    @Basic(optional = false)
    @Column(name = "PRICE")
    private double price;
    @Basic(optional = false)
    @Column(name = "NUMBEROFPAGE")
    private int numberofpage;

    public Book()
    {
    }

    public Book(Integer id)
    {
        this.id = id;
    }

    public Book(Integer id, String title, String description, double price, int numberofpage)
    {
        this.id = id;
        this.title = title;
        this.description = description;
        this.price = price;
        this.numberofpage = numberofpage;
    }

    public Integer getId()
    {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getNumberofpage() {
        return numberofpage;
    }

    public void setNumberofpage(int numberofpage) {
        this.numberofpage = numberofpage;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Book)) {
            return false;
        }
        Book other = (Book) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.entity.Book[id=" + id + "]";
    }
}
我的Junit测试类:


public class BookTest
{

    private static EntityManager em;
    private static EntityManagerFactory emf;

    public BookTest()
    {

    }

    @BeforeClass
    public static void setUpClass() throws Exception
    {
        emf = Persistence.createEntityManagerFactory("E01R01PU");
        em = emf.createEntityManager();
    }

    @AfterClass
    public static void tearDownClass() throws Exception
    {
        em.close();
        emf.close();
    }

    @Test
    public void createBook()
    {
        Book book = new Book();
        book.setId(1);
        book.setDescription("Mastering the Behavior Driven Development with Ruby on Rails");
        book.setTitle("Mastering the BDD");
        book.setPrice(25.9f);
        book.setNumberofpage(1029);

        em.persist(book);

        assertNotNull("ID should not be null", book.getId());
    }
}
My persistence.xml


<persistence>
  <persistence-unit name="E01R01PU" transaction-type="JTA">
    <jta-data-source>BookstoreJNDI</jta-data-source>
    <properties />
  </persistence-unit>
</persistence>
您首先有一个“由以下原因引起的”:java.lang.ClassNotFoundException:com.sun.gjc.spi.ResourceAdapter
“输出中存在错误。这应该是你应该修复的第一件事(丢失的东西)。另一方面,我在你们的书课上看到了这么多的注释,大多数都是不需要的。特别是列名。顺便问一下:为什么要注释属性而不是getter?您已经覆盖了equals(),但没有真正实现它(仅针对Id字段,其他字段呢?)。如果需要覆盖equals,还必须覆盖hashCode。让IDE创建它们会简单得多。

首先,您的类路径上缺少一些jar,我的建议是添加
$GF\u HOME/modules/GF client.jar
(不要将jar复制到您的项目中,直接指向它)

其次,您的测试在当前状态下无法通过,它缺少一些部分:

  • persist
    需要在事务内部调用
  • 您需要
    刷新
    更改以获得分配的ID
下面是一个改进版本,它将使用自己的
EntityManager
在事务内部运行每个测试方法(在测试方法结束时回滚):

奖励:此测试将通过:)

注意,人们通常更喜欢在不启动容器的情况下运行测试,即不依赖JNDI。下面是一个
persistence.xml
,显示了如何配置EclipseLink以连接到在服务器模式下运行的Derby数据库,您可以在测试上下文中使用该数据库:

<?xml version="1.0" encoding="UTF-8"?>
<persistence
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">

  <persistence-unit name="TestPu" transaction-type="RESOURCE_LOCAL">
    <class>com.acme.Foo</class>

    <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
      <!--property name="eclipselink.target-database" value="DERBY"/-->
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527//path/to/derbyDBs/TestDB;create=true"/>
      <property name="javax.persistence.jdbc.user" value="APP"/>
      <property name="javax.persistence.jdbc.password" value="APP"/>

      <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>

      <property name="eclipselink.weaving" value="static" />

      <property name="eclipselink.debug" value="ALL"/>
      <property name="eclipselink.logging.level.sql" value="FINEST" />
      <property name="eclipselink.logging.level" value="FINEST" />
      <property name="eclipselink.logging.level.cache" value="FINEST" />
    </properties>
  </persistence-unit>
</persistence>

com.acme.Foo
假的

在OK中注释属性(您甚至可以将属性和getter注释与JPA2.0混合使用)。此外,当前的
equals
实现对于JPA来说是很好的(如果两本书有相同的主键,从JPA的角度来看,它们应该是相同的),OP确实实现了
hashCode
。使用PK而不是商业密钥是有争议的,但那是另一回事。我遵循你的指示,它起了作用。但是当我创建RESTWeb服务时,我无法构建我的项目。以下是消息:app\u path\build impl.xml:583:模块尚未部署。生成失败。那么我现在该怎么办?@Zeck你应该接受这个答案,然后再提出一个问题:)请不要在同一个问题中混用不同的主题。+1对于gf-client.jar,我尝试解决这个问题;你真的是唯一一个使用JEE/Glassfish的专家吗?:)@凯文:当然,我不是唯一一个。但我确实对JavaEE和应用服务器(包括GF)有一些经验。
public class BookTest {
    private static EntityManager em;
    private static EntityManagerFactory emf;

    @BeforeClass
    public static void createEntityManagerFactory() {
        emf = Persistence.createEntityManagerFactory("E01R01PU");
    }

    @AfterClass
    public static void closeEntityManagerFactory() throws Exception {
        emf.close();
    }

    @Before
    public void beginTransaction() {
        em = emf.createEntityManager();
        em.getTransaction().begin();
    }

    @After
    public void rollbackTransaction() {
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }

        if (em.isOpen()) {
            em.close();
        }
    }

    @Test
    public void createBook() {
        Book book = new Book();
        book.setId(1);
        book.setDescription("Mastering the Behavior Driven Development with " +
                            "Ruby on Rails");
        book.setTitle("Mastering the BDD");
        book.setPrice(25.9f);
        book.setNumberofpage(1029);

        em.persist(book);
        em.flush(); // sync the in-memory changes with the db
        // now this will pass
        assertNotNull("ID should not be null", book.getId()); 
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">

  <persistence-unit name="TestPu" transaction-type="RESOURCE_LOCAL">
    <class>com.acme.Foo</class>

    <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
      <!--property name="eclipselink.target-database" value="DERBY"/-->
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527//path/to/derbyDBs/TestDB;create=true"/>
      <property name="javax.persistence.jdbc.user" value="APP"/>
      <property name="javax.persistence.jdbc.password" value="APP"/>

      <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>

      <property name="eclipselink.weaving" value="static" />

      <property name="eclipselink.debug" value="ALL"/>
      <property name="eclipselink.logging.level.sql" value="FINEST" />
      <property name="eclipselink.logging.level" value="FINEST" />
      <property name="eclipselink.logging.level.cache" value="FINEST" />
    </properties>
  </persistence-unit>
</persistence>