Java 单元测试、集成测试还是设计中的问题?

Java 单元测试、集成测试还是设计中的问题?,java,unit-testing,hibernate,integration-testing,Java,Unit Testing,Hibernate,Integration Testing,我编写了我的第一个单元测试,我认为它过于依赖于其他模块,我不确定这是否是因为: 这是一个复杂的测试 实际上,我已经编写了一个集成测试或 我的设计有问题 我首先要说的是,尽管我有大约4年的开发经验,但我从未学习过,也没有人教过自动测试。 我刚刚用Hibernate完成了DAL实现中的一项重大更改,我的一位同事建议我为新部件编写单元测试。 主要的变化是切换到按请求会话模式,以及更具建设性地使用应用程序事务。 由于上述更改的性质,单元测试从特定请求到达并开始事务的点开始,测试在事务结束后结束,并检

我编写了我的第一个单元测试,我认为它过于依赖于其他模块,我不确定这是否是因为:

  • 这是一个复杂的测试
  • 实际上,我已经编写了一个集成测试或
  • 我的设计有问题
我首先要说的是,尽管我有大约4年的开发经验,但我从未学习过,也没有人教过自动测试。
我刚刚用Hibernate完成了DAL实现中的一项重大更改,我的一位同事建议我为新部件编写单元测试。
主要的变化是切换到按请求会话模式,以及更具建设性地使用应用程序事务。
由于上述更改的性质,单元测试从特定请求到达并开始事务的点开始,测试在事务结束后结束,并检查事务是否执行了它应该执行的更改。
这一测试涉及初始化以下对象:

  • 内存中的数据库-这样就有数据可供处理
  • 初始化公司记录器-因为方法取决于它
  • 初始化设计为单例的存储库它是函数通向DAL的大门,但它也存储其他东西,因此它是一个需要创建的大对象
  • 初始化请求处理程序,它也是一个单例-这保存了要测试的方法
我想我实际上已经编写了一个集成测试,因为我需要初始化DB、Hibernate和存储库,但我不确定如果测试方法使用所有这些对象进行操作,我怎么能编写它,我想看看事务处理是如何执行的(这是在测试方法上完成的)

我很感激所有的评论和想法,如果它们不够清楚,我会很乐意详细说明或澄清

谢谢,
伊泰

另外,
HibernateSessionFactory
实际上是
HibernateUtil
一书中众所周知的
HibernateUtil
,由于历史原因被错误命名

public class AdminMessageRepositoryUpdaterTest {
private static WardId wardId;
private static EmployeeId employeeId;
private static WardId prevWardId;
private static EmployeeId prevEmployeeId;

@Test
public void testHandleEmployeeLoginToWard(){
    AgentEmployeesWardsEngine agentEmployeesWardsEngine = new AgentEmployeesWardsEngine();
    AgentEngine agentEngine = new AgentEngine();
    //Remove all entries from AgentEmployeesWards table
    HibernateSessionFactory.beginTransaction();
    for (Agent agent : agentEngine.findAll()){
        agentEmployeesWardsEngine.removeAgentEntries(agent.getId());
    }
    HibernateSessionFactory.commitTransaction();//no need to try catch as this is done in a controlled environment
    int i=0;
    //build expectedSet
    Set<AgentEmployeesWards> expectedMappingsToChangeSet = new HashSet<AgentEmployeesWards>();
    //Mappings which should have ward updated
    expectedMappingsToChangeSet.add(new AgentEmployeesWards(new AgentId(1).getValue(), employeeId.getValue(), prevWardId.getValue(), true, TimestampUtils.getTimestamp(), i++));
    expectedMappingsToChangeSet.add(new AgentEmployeesWards(new AgentId(2).getValue(), employeeId.getValue(), prevWardId.getValue(), true, TimestampUtils.getTimestamp(), i++));
    //Mappings which should have employee updated
    expectedMappingsToChangeSet.add(new AgentEmployeesWards(new AgentId(3).getValue(), prevEmployeeId .getValue(), wardId.getValue(), false, TimestampUtils.getTimestamp(), i++));
    expectedMappingsToChangeSet.add(new AgentEmployeesWards(new AgentId(4).getValue(), prevEmployeeId.getValue(), wardId.getValue(), false, TimestampUtils.getTimestamp(), i++));

    //Prepare clean data for persistence
    Set<AgentEmployeesWards> cleanSet = new HashSet<AgentEmployeesWards>(expectedMappingsToChangeSet);
    //Mappings which should NOT have ward updated
    cleanSet.add(new AgentEmployeesWards(new AgentId(5).getValue(), employeeId.getValue(), prevWardId.getValue(), false, TimestampUtils.getTimestamp(), i++));
    cleanSet.add(new AgentEmployeesWards(new AgentId(6).getValue(), employeeId.getValue(), prevWardId.getValue(), false, TimestampUtils.getTimestamp(), i++));
    //Mappings which should NOT have employee updated
    cleanSet.add(new AgentEmployeesWards(new AgentId(7).getValue(), prevEmployeeId .getValue(), wardId.getValue(), true, TimestampUtils.getTimestamp(), i++));
    cleanSet.add(new AgentEmployeesWards(new AgentId(8).getValue(), prevEmployeeId.getValue(), wardId.getValue(), true, TimestampUtils.getTimestamp(), i++));
    HibernateSessionFactory.beginTransaction();
    for (AgentEmployeesWards agentEmployeesWards : cleanSet){
        agentEmployeesWardsEngine.saveNewAgentEmployeesWardsEntry(agentEmployeesWards);
    }
    HibernateSessionFactory.commitTransaction();//no need to try catch as this is done in a controlled environment
    //Close the session as to neutralize first-level-cache issues
    HibernateSessionFactory.closeSession();
    //Perform the action so it can be tested
    AdminMessageReposityUpdater.getInstance().handleEmployeeLoginToWard(employeeId, wardId, TimestampUtils.getTimestamp());

    //Close the session as to neutralize first-level-cache issues
    HibernateSessionFactory.closeSession();

    //Load actualSet from DAL
    Set<AgentEmployeesWards> actualSet = new HashSet<AgentEmployeesWards>(agentEmployeesWardsEngine.findByPrimaryEmployeeId(employeeId));
    actualSet.addAll(agentEmployeesWardsEngine.findByPrimaryWardId(wardId));

    //Prepare expected
    Set<AgentEmployeesWards> expectedSet = new HashSet<AgentEmployeesWards>();
    for (AgentEmployeesWards agentEmployeesWards : expectedMappingsToChangeSet){
        //We need to copy as the wardId and employeeId are properties which comprise the equals method of the class and so 
        //they cannot be changed while in a Set
        AgentEmployeesWards agentEmployeesWardsCopy = new AgentEmployeesWards(agentEmployeesWards);
        if (agentEmployeesWardsCopy.isEmployeePrimary()){
            //If this is a employee primary we want it to be updated to the new org-unit id
            agentEmployeesWardsCopy.setWardId(wardId.getValue());
        } else {
            //Otherwise we want it to be updated to the new employee id
            agentEmployeesWardsCopy.setEmployeeId(employeeId.getValue());
        }
        expectedSet.add(agentEmployeesWardsCopy);
    }
     //Assert between actualSet and expectedSet
    // Assert actual database table match expected table
   assertEquals(expectedSet, actualSet);


}
@BeforeClass
public static void setUpBeforeClass() throws SQLException,ClassNotFoundException{
    Class.forName("org.h2.Driver");
    Connection conn = DriverManager.getConnection("jdbc:h2:mem:MyCompany", "sa", "");

    ConfigurationDAO configDAO = new ConfigurationDAO();
    HibernateSessionFactory.beginTransaction();
    configDAO.attachDirty(new Configuration("All","Log", "Level", "Info",null));
    configDAO.attachDirty(new Configuration("All","Log", "console", "True",null));
    configDAO.attachDirty(new Configuration("All","Log", "File", "False",null));

    HibernateSessionFactory.commitTransaction();
    Logger log = new Logger();
    Server.getInstance().initialize(log);
    Repository.getInstance().initialize(log);
    AdminMessageReposityUpdater.getInstance().initialize(log);

    AdminEngine adminEngine = new AdminEngine();
    EmployeeEngine employeeEngine = new EmployeeEngine();
    HibernateSessionFactory.beginTransaction();
    Ward testWard = new Ward("testWard", 1, "Sales", -1, null);
    adminEngine.addWard(testWard);
    wardId = new WardId(testWard.getId());
    Ward prevWard = new Ward("prevWard", 1, "Finance", -1, null);
    adminEngine.addWard(prevWard);
    prevWardId = new WardId(prevWard.getId());

    Employee testEmployee = new Employee("testEmployee", "test", null, "employee", "f", prevWardId.getValue(), null, false, true);
    employeeEngine.setEmployee(testEmployee);
    employeeId = new EmployeeId(testEmployee.getId());

    Employee prevEmployee = new Employee("prevEmployee", "prev", null, "employee", "f", wardId.getValue(), null, false, true);
    employeeEngine.setEmployee(prevEmployee);
    prevEmployeeId = new EmployeeId(prevEmployee.getId());
    HibernateSessionFactory.commitTransaction();
    HibernateSessionFactory.closeSession();
}
@AfterClass
public static void tearDownAfterClass(){
    AdminEngine adminEngine = new AdminEngine();
    EmployeeEngine employeeEngine = new EmployeeEngine();
    HibernateSessionFactory.beginTransaction();
    employeeEngine.removeEmployeeById(employeeId);
    employeeEngine.removeEmployeeById(prevEmployeeId);
    adminEngine.removeWardById(wardId);
    adminEngine.removeWardById(prevWardId);
    HibernateSessionFactory.commitTransaction();
    HibernateSessionFactory.closeSession();
}
}
公共类AdminMessageRepositoryUpdateTest{
私有静态WardId WardId;
私有静态EmployeeId EmployeeId;
私有静态WardId-prevWardId;
私有静态EmployeeId previemployeeid;
@试验
public void testHandleEmployeeLoginToWard(){
AgentTemployeesWardEngine AgentTemployeesWardEngine=新的AgentTemployeesWardEngine();
AgentEngine AgentEngine=新AgentEngine();
//从AgentTemployesWards表中删除所有条目
HibernateSessionFactory.beginTransaction();
for(代理:agentEngine.findAll()){
removeAgentEntries(agent.getId());
}
HibernateSessionFactory.commitTransaction();//无需尝试捕获,因为这是在受控环境中完成的
int i=0;
//构建期望集
Set expectedMappingsToChangeSet=new HashSet();
//应该更新的映射
expectedMappingsToChangeSet.add(新的AgentTemployesWards(新的AgentId(1).getValue(),employeeId.getValue(),prevWardId.getValue(),true,TimeStamp(),i++);
expectedMappingsToChangeSet.add(新的AgentTemployesWards(新的AgentId(2).getValue(),employeeId.getValue(),prevWardId.getValue(),true,TimeStamp(),i++);
//应该更新员工的映射
expectedMappingsToChangeSet.add(新的AgentTemployesWards(新的AgentId(3).getValue(),PreveEmployeeId.getValue(),wardId.getValue(),false,TimeStamp(),i++);
expectedMappingsToChangeSet.add(新的AgentTemployesWards(新的AgentId(4).getValue(),PrevenEmployeeId.getValue(),wardId.getValue(),false,TimesUtils.getTimestamp(),i++);
//为持久性准备干净的数据
Set cleanSet=new HashSet(expectedMappingsToChangeSet);
//不应更新的映射
add(new agentTemployesWards(new AgentId(5).getValue(),employeeId.getValue(),prevWardId.getValue(),false,TimestampUtils.getTimestamp(),i++));
add(new agentTemployesWards(new AgentId(6).getValue(),employeeId.getValue(),prevWardId.getValue(),false,TimestampUtils.getTimestamp(),i++));
//不应更新员工的映射
add(新的agentTemproyEEswards(新的AgentId(7).getValue(),preveEmployeeId.getValue(),wardId.getValue(),true,TimestampUtils.getTimestamp(),i++);
add(new agentTemproyEEswards(new AgentId(8).getValue(),preveEmployeeId.getValue(),wardId.getValue(),true,TimestampUtils.getTimestamp(),i++);
HibernateSessionFactory.beginTransaction();
适用于(AgentTemployesWards AgentTemployesWards:cleanSet){
AgentTemproyEESwardEngine.SaveNewAgentTemproyEESwardsEntry(AgentTemproyEESwards);
}
HibernateSessionFactory.commitTransaction();//无需尝试捕获,因为这是在受控环境中完成的
//关闭会话以消除一级缓存问题
HibernateSessionFactory.closeSession();
//执行该操作,以便对其进行测试
AdminMessageReposityUpdater.getInstance().handleEmployeeLoginToWard(employeeId、wardId、TimestampUtils.getTimestamp());
//关闭会话以消除一级缓存问题
HibernateSessionFactory.closeSession();
//从DAL加载实际设置
Set actualSet=new HashSet(agentemployeeswardengine.findbyprimaryeemployeeid(employeeId));
actualSet.addAll(agentTemployeesWardEngine.findByPrimaryWardId(wardId));
//准备预期
Set expectedSet=new HashSet();
对于(AgentTemproyEEswards AgentTemproyEEswards:expectedMappingsToChangeSet){
//我们需要复制,因为wardId和employeeId是组成类的equals方法的属性,所以
//它们在集合中时无法更改
AgentTemployEESwards AgentTemployEESwards copy=新的AgentTemployEESwards(AgentTemployEESwards);
如果(a)