-1

私は JUnit テストを始めたばかりで、それがどのように機能するのかに興味があります。現在、ユニットテストに合格しようとしています。

テスト方法は

@Test
  public void ensure_equals_method_is_properly_coded ()
  {
    assertTrue(employees.get(0).equals(employees.get(2)));
    assertFalse(employees.get(0).equals(employees.get(1)));
    assertFalse(employees.get(0).equals(employees.get(3)));
  }

既に値が入力されている ArrayList があります。私が理解していることから、このテストを自分のタスクに渡すために equals() というメソッドを作成することを想定しています。私の質問は、このメソッドがテスト対象のメソッドをどのように見つけるかです。Persons というクラスに equals() メソッドを作成しましたが、テストを実行したときにそれが呼び出されているかどうかさえわかりません。

2 番目の質問は、equal() メソッドのロジックについて質問することです。これまでのところ、私はこれを持っています。

public boolean equals() {
      if (employees.get(0).equals(employees.get(2))) 

          return true;
    return false;
  }

最初のテスト項目が true をアサートするため、これは true を返すはずです。これについて私の論理は正しいですか?

わかりやすくするために、ここに私の完全な Test クラスを示します。すべてが既に存在します。

public class Tests 
{
  List<Person> employees = new ArrayList<Person>();

  @Before
  public void init ()
  {
    Person anEmployee = new Employee();
    anEmployee.setName("Trevor Page");
    anEmployee.setSex("Male");
    Calendar cal = Calendar.getInstance();
    cal.set(1983, 0, 1);
    anEmployee.setBirthday(cal.getTime());
    ((Employee)anEmployee).setJobTitle("Sr. Software Engineer");
    ((Employee)anEmployee).setOrganization(new Google("Google"));
    employees.add(anEmployee);

    anEmployee = new Employee();
    anEmployee.setName("Jane Doe");
    anEmployee.setSex("Female");
    anEmployee.setBirthday(cal.getTime());
    ((Employee)anEmployee).setJobTitle("Sr. Software Engineer");
    ((Employee)anEmployee).setOrganization(new Google("Google"));
    employees.add(anEmployee);

    anEmployee = new Employee();
    anEmployee.setName("Trevor Page");
    anEmployee.setSex("Male");
    anEmployee.setBirthday(cal.getTime());
    ((Employee)anEmployee).setJobTitle("Sr. Software Engineer");
    ((Employee)anEmployee).setOrganization(new Google("Google"));
    employees.add(anEmployee);

    anEmployee = new Employee();
    anEmployee.setName("Trevor Page");
    anEmployee.setSex("Male");
    anEmployee.setBirthday(cal.getTime());
    ((Employee)anEmployee).setJobTitle("Sr. Software Engineer");
    ((Employee)anEmployee).setOrganization(new Microsoft("Microsoft"));
    employees.add(anEmployee);
  }

  @Test
  public void ensure_toString_method_is_properly_coded()
  {
    String message = "Name: Trevor Page, Sex: Male" +
    "\nJob Title: Sr. Software Engineer, Organization: Google";

    assertThat(employees.get(0).toString(), is(message));
  }

  @Test
  public void ensure_equals_method_is_properly_coded ()
  {
    assertTrue(employees.get(0).equals(employees.get(2)));
    assertFalse(employees.get(0).equals(employees.get(1)));
    assertFalse(employees.get(0).equals(employees.get(3)));
  }

これが、Abstract である完全な Persons クラスです。私はすでに最初のテストケースを動作させています。

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


public abstract class Person 
{
  public abstract String getName();
  public abstract String getSex();
  public abstract void setName(String name);
  public abstract void setSex(String sex);
  public abstract void setBirthday(Date birthdate);
  public abstract Date getBirthday();
  public abstract String getJobTitle();
  public abstract String getNameOfOrganization();



  List<Person> employees = new ArrayList<Person>();



  @Override
  public String toString() {  


    return "Name: " + getName() + ", Sex: " + getSex() + "\n" + "Job Title: " + getJobTitle() + ", Organization: " + getNameOfOrganization() ;

     }

}

この抽象クラスを拡張する Employee という別のクラスがあります。

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Employee extends Person

{

    List<String> employees = new ArrayList<String>();

    @Override
    public String getName() {
        employees.add("Trevor Page");

        return employees.get(0);
    }

    @Override
    public String getSex() {

        employees.add("Male");
        return employees.get(1);

    }

    @Override
    public void setName(String name) {
        // TODO Auto-generated method stub

    }

    @Override
    public void setSex(String sex) {
        // TODO Auto-generated method stub

    }

    @Override
    public void setBirthday(Date birthdate) {
        // TODO Auto-generated method stub

    }

    @Override
    public Date getBirthday() {
        // TODO Auto-generated method stub
        return null;
    }

    public void setJobTitle(String string) {
        // TODO Auto-generated method stub

    }

    public String getJobTitle() {

        employees.add("Sr. Software Engineer");

        return employees.get(2);
    }

    public void setOrganization(Google google) {
        // TODO Auto-generated method stub

    }

    public void setOrganization(Microsoft microsoft) {
        // TODO Auto-generated method stub

    }

    @Override
    public String getNameOfOrganization() {
        employees.add("Google");
        return employees.get(3);
    }

}

運良く最初のテストを実行することができました。単体テストが私の値をテストする方法を知っているかどうかはわかりません。

4

3 に答える 3

0

equalsperson クラスに実装した場合、2 人の人物が等しいかどうかをアサートできます。

あなたが上に持っているものは

Person p1 = employees.get(0);
Person p2 = employees.get(2);
assertTrue(p1.equals(p2));

上記では、equals メソッドを直接呼び出しています。

しかし、あなたもそうするかもしれません

assertEquals(p1,p2);

その場合、Person.equalsメソッドはフードの下で呼び出されます。

assertEqualsassertTrue、および他のいくつかのメソッドは、次のようにクラスassertFalseから静的にインポートできます。org.junit.Assert

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;

または、はるかに単純な形式import static org.junit.Assert.*;

equals の実装は、ある従業員が別の従業員と等しいかどうかを単純に検証する必要があります。あなたが暗示しているように、従業員のリストについて知る必要はありません。

例えば

class Person {
   public boolean equals(Object o) {
      if(this==o) {
         return true; 
      }
      if(o instanceof Person) {
         Person other = (Person) o;
         return (this.name == other.name) || (this.name != null && this.name.equals(other.name);
      }
      reurn false;
   }
}

テストは、このequals実装が正しいこと、つまり、対称性、推移性、反射性などのプロパティを満たしていることを確認することで構成されObject.equalsます。これについて詳しくは、メソッドの javadoc を参照してください。

于 2013-09-28T02:57:43.840 に答える
0

equalsメソッドがテストで呼び出されていないことを述べることから始めましょう。Object.equals(Object o)の代わりに効果的に呼び出していPerson.equals()ます。サインの違いわかりますか?メソッドはパラメーターを取りませequalsんが、これは珍しいことです。同等性を他のものと比較する必要があります。

また、テストの設定が不適切です。検証するテスト データの単位を確立する必要があります。不要なデータ構造を排除します。equals()つまり、呼び出しで 2 つのオブジェクトしか比較していないということです。

この2つの問題を解決しましょう。

メソッドequalsをオーバーライドする必要がありますObject.equals。そのためには、同じシグネチャを持つメソッドを作成します。

@Override
public boolean equals(Object other) {
    // What makes two Person instances equivalent?
}

この実装はあなたに任せます。の場合を考慮してotherくださいnull

次に、テスト。私が好むテストの設定方法は、小さなチャンクで行うことです。このロジックをテストする際には、いくつかの点を確認する必要があります。

  • 2 つのインスタンスの値は同じですか?
  • に対して同じ値を持っていhashCode()ますか? (これは、2 つのオブジェクトが等しい場合、それらの hashCode も等しいという規則です。)
  • インスタンスが異なる場合、それらは等しいですか? EG と aPersonを比較するIntegerと...
  • インスタンスの 1 つが である場合、それらは等しいですnullか?

少なくとも、これは 4 つのテスト ケースです。

@Test
public void equals_equivalentInstances() {
    // given
    // two objects that are initialized in the exact same way
    // when + then
    // call the equals() method and assert that the statement is true
}


@Test
public void equals_hashCodeMatches() {
    // given
    // two objects that are initialized in the exact same way
    // when + then
    // call the hashCode() method of both and assert their equivalence
}


@Test
public void equals_handlesDifferentObjectTypes() {
    // given
    // a Person class and some other Object
    // when + then
    // call the equals() method and assert that they are not equal
}

@Test
public void equals_handlesNull() {
    // given
    // two Person classes, one of them initialized to null
    // when + then
    // call the equals() method and assert that they are not equal
}
于 2013-09-28T03:16:22.630 に答える