在断言之前测试被测对象是否为空的正确方法

时间:2017-10-30 20:54:40

标签: java unit-testing junit

我写了我的第一个测试,我想问你,如果我的测试是正确的。如果在更新方法之后更新某个对象,我需要测试,所以这是我的测试结构:

@Test
public void myTest {
   // init myObj variable which I want test
   // myObjService is my service for my object which I've initialized in @Before tagged function
   MyObj myObj = myObjService.getById(465);

   // test if that variable is initialized, and it is not null
   Assert.assertNotNull(myObj);

   // update some properties of myObj
   myObj.setX(...);
   myObj.setY(...);
   ...

   // call update function which update obj in collection by Id of object
   myObjService.update(myObj);

   // get object with same id which should be with updated properties
   MyObj myUpdatedObj = myObjService.getById(465);

   // test that properties
   Assert.assertEquals(myObj.getX(), myUpdatedObj.getX());
   Assert.assertEquals(myObj.getY(), myUpdatedObj.getY());
   ...
}

该程序是否正确或我应该编辑某些内容?

3 个答案:

答案 0 :(得分:1)

此过程缺少确保在测试开始时字段未设置为新值的关键步骤。

将这些行添加到测试中:

<?php
  if (array_key_exists('email', $_POST) OR array_key_exists('password', $_POST)) {
    $link = mysqli_connect("localhost", "root", "", "users");

    if (mysqli_connect_error()){
      die ("Error connecting");
    }


    if ($_POST['email'] == ''){
      echo "<p>Email address is required</p>";
    } else if ($_POST['password'] == ''){
      echo "<p>Password is required</p>";
    } else {
      $query = "SELECT `id` FROM `users` WHERE email = '".mysqli_real_escape_string($link, $_POST['email'])."'";
      $result = mysqli_query($link, $query);
      if (mysqli_num_rows($result) > 0) {
        echo "<p>That Email address already has an account<p>";
    } else {
      $query = "INSERT INTO `users` (`email`, `password`) VALUES ('".mysqli_real_escape_string($link, $_POST['email'])."',
       '".mysqli_real_escape_string($link, $_POST['password'])."')";

       if (mysqli_query($link, $query)) {
         echo "<p>You have been signed up!</p>";
       } else {
         echo "<p>There was a problem, please try again later</p>";
       }
    }
  }
}

?>

答案 1 :(得分:1)

为什么你需要空检查?你寻求什么好处?这是因为:

  1. 您可以通过准备测试本身中的所有测试数据来显式控制是否可以使用null。
  2. 如果由于某种原因你无法做到这一点 - 你还需要从测试中清楚地说明失败时发生的事情。您可以通过堆栈跟踪中的NPE轻松找到它。所以我不会用额外的线条来测试测试。特别是考虑到在你的情况下,由于测试设置中的错误,更有可能发生null。
  3. 我的建议是准备测试中的所有数据:

    public void updatesAllFieldsOfDog() {
        //creates object with random values
        Dog original = dao.createDog(Dog.random());
        //create new object with random fields and set the ID to the original
        //which effectively means - original object with all fields updated
        Dog updated = Dog.random().setId(original.getId());
        dao.updateDog(updated);
        Dog fromDb = dao.getDog(original.getId());
        //Method from Unitils that compares all the fields
        assertReflectionEquals(updated, fromDb);
    }
    

    如果您对细节感兴趣,可以找到类似的测试here

答案 2 :(得分:1)

首先,你可以拆分它。

@Test
public void retreiveMyObjTest {
   // GIVEN
   Integer myObjId = 465;
   // WHEN
   MyObj myObj = myObjService.getById(465);
   // THEN
   Assert.assertNotNull(myObj);
   Assert.assertEquals(myObjId, myObj.getId());
   ...
}
@Test
public void updateMyObjTest {
   // GIVEN
   MyObj myObj = myObjService.getById(465);
   // WHEN
   myObj.setX(...);
   myObj.setY(...);
   myObjService.update(myObj);
   MyObj myUpdatedObj = myObjService.getById(465);
   // THEN
   Assert.assertEquals(myObj.getX(), myUpdatedObj.getX());
   Assert.assertEquals(myObj.getY(), myUpdatedObj.getY());
   ...
}

但在大多数情况下,您无法预测ID 465是否在您的数据库中。您应该为此找到更抽象的内容,或者您​​应该仅使用另一个数据库进行测试。