Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单元测试处理数据库记录的函数_Java_Unit Testing_Tdd - Fatal编程技术网

Java 单元测试处理数据库记录的函数

Java 单元测试处理数据库记录的函数,java,unit-testing,tdd,Java,Unit Testing,Tdd,单元测试应该只测试一个函数的逻辑,并且应该“模拟”该函数中使用的数据。我想知道我们如何将下面的函数与“模拟”数据结合起来?即使这是正确的方法。函数签名是 public String doSomething(int firstId, int secondId, int count){ //this function looks in a table e.g. C which has foreign keys from table A, and B //if firstId

单元测试应该只测试一个函数的逻辑,并且应该“模拟”该函数中使用的数据。我想知道我们如何将下面的函数与“模拟”数据结合起来?即使这是正确的方法。函数签名是

    public String doSomething(int firstId, int secondId, int count){
     //this function looks in a table e.g. C which has foreign keys from table A, and B
    //if firstId and secondId exist in db table C return "already-exists"
    //if count < a_column_value_in_table_C return "not-allow"
    // else return "success"
    }
公共字符串doSomething(int firstId、int secondId、int count){
//此函数在表中查找,例如C,其中包含表a和B中的外键
//如果数据库表C中存在firstId和secondId,则返回“已存在”
//如果计数<表中的列值,返回“不允许”
//否则返回“成功”
}
firstId
secondId
是两个不同表中的外键。现在,我们如何从以下方面对该函数进行单元测试: 1.单元测试应如何设计,以便能够在功能中测试3个Scnario
2.考虑到单元测试需要来自两个不同表的外键,我们如何为单元测试准备数据

我通常使用getById和getAll函数创建一个存储库接口。出于测试目的,我创建了一个inmemory存储库,出于生产目的,我使用数据库存储库

这里有一个例子:

public interface Repository<T> {
  public T getById(int Id);
  public List<T> getAll();
}

public InmemoryRepository implements Repository<User> {
 List<User> database = new ArrayList<>(); //with some data
 public List<User> getAll() { 
  return database;
 }
 public User get(int Id) {
   return database.stream().filter(x -> x.Id = Id).collect(Collectors.asList());
 }
}
公共接口存储库{
公共T getById(int Id);
公共列表getAll();
}
公共InmemoryRepository实现了存储库{
List database=new ArrayList();//包含一些数据
公共列表getAll(){
返回数据库;
}
公共用户get(int-Id){
返回database.stream().filter(x->x.Id=Id).collect(Collectors.asList());
}
}
在您的函数中,您可以插入此存储库,以便通过以下方式访问数据库:

public String doSomething(int firstId, int secondId, int count, Repository<User> repo){};
publicstringdosomething(intfirstid,intsecondid,int count,repo存储库){};

您可以使用一些测试数据库或内存数据库(如HSQLDB)。在测试之前用一些测试数据填充它(在带注释的方法
@BeforeClass
中,或者在测试数据源初始化期间,如果使用Spring)。然后通过准备好的数据对所有场景执行测试。用
@AfterClass
注释的方法清理测试数据库中的数据

如果您在XML配置中为测试数据源使用Spring和configuration,则可能如下所示:

<jdbc:embedded-database id="dataSource" type="HSQL" >
  <jdbc:script location="scripts/ddl/*"/> <!-- create tables -->
  <jdbc:script location="scripts/dml/*"/> <!-- populate test data -->
</jdbc:embedded-database>

您应该使用Solid principles中的依赖项注入。 doSomething方法的所有者类应该注入一些存储库或DAO等

在单元测试中,应该模拟存储库方法

例如,假设doSomething方法调用存储库的findById(…)方法。您应该通过所需的输出模拟findById方法,并只测试流的逻辑部分

  • 您不应该设计一个单元测试来匹配所有的情况。对于每种情况,创建不同的单元测试

  • 您需要模拟访问数据库的存储库或类,以便它不会在数据库中执行,而是返回您在单元测试中预先确定的结果集。有模拟库,这使您的工作非常容易。如果代码只是执行一个查询或过程并返回结果,那么为它编写一个单元测试就没有什么好处了,在这种情况下编写一个集成测试就足够了


  • 附言:Emre Savcı,依赖注入不是一个可靠的原则,依赖反转是。他们根本没有关系

    //此函数在表中查找,例如C..
    ”-此函数如何执行此操作?我想通过一些JDBC层,例如CRUD存储库?如果是这样的话:模拟并注入这个层----“…因此它能够测试3个scnarios…”-三个场景,三个不同的测试,三个不同的模拟。hi@Turing85在测试类使用“真实”存储库时,使用模拟存储库是有意义的,我仍然不完全理解这将如何工作,但我会研究它,但你的方法是有意义的使用模拟积垢deposIf这个答案帮助你,请标记为接受。如果没有,请为我进一步澄清。