同じFunciton /コンストラクタにMockito繰り返しメソッド呼び出しは、テストされています

コールドケルベロス:

ここではクラスがあります Person

public class Person {
    // ...
    public String getInfo(String key)
            return key; //for brevity
    }
}

そして、別のクラスには、Student上の依存関係を持つPerson(現在の実装では、問題の一部であり、我々はこれら2つのクラスを変更できないことに注意してください)

public class Student {
    private String copyFirstName;
    private String otherInfo;

    private Person person;
    Student(Person p) {
        person = p;

        copyFirstName = person.getInfo("firstName")

        if (copyFirstName == null || copyFirstName.equals("")) { //entry point A
            throw new SomethingError("message here");
        }

        otherInfo = person.getInfo("bio")

        if (otherInfo == null || otherInfo.equals("")) { // entry point B
            throw new SomethingError("message here");
        }
    }
}

クラスは、上記の非現実的に見えるが、我々は変更できないという問題の一部としてそれを取ることがあります。

目標は、テストのすべての行を完全にカバーを持つことです。これを行うために、私は2つのカバーするために2つのテストする予定if文をと方法を模擬getInfo私は、コンストラクタの第二の試験のために、「エントリポイントA」をスキップする際に知っているようにパラメータが渡されているものに注目しながら、を。

理想的には、これは私のJUnitのクラスになります

public class StudentTest {
    private Person person;
    private Student student;
    private Person mockedPerson;

    @Before
    public void init()
    throws SomethingError  {
        person = new Person();
        student = new Student();
        mockedPerson = Mockito.mock(Person.class);
    }

    @Test(expected=SomethingError.class)
    public void myTest1()
    throws SomethingError {
        Mockito.when(mockedPerson.getInfo("firstName"))
        .thenAnswer(
            new Answer<String>(){
            @Override
            public String answer(InvocationOnMock invocation) {
                String arg = invocation.getArgumentAt(0, String.class);
                System.out.println(arg);
                if (arg.equals("firstName")) {
                    return null;
                }
                return person.getInfo(arg); // default value
            }});

        try {
            new Student(mockedPerson);
            fail();
        } catch (MultilingualException e) {
            Mockito.reset(mockedPerson); // not sure if this works
            assertEquals(e.getMessage(), "message here");
        }
    }

    @Test(expected=SomethingError.class)
    public void myTest2()
    throws SomethingError {
        Mockito.when(mockedPerson.getInfo("bio"))
        .thenAnswer(
            new Answer<String>(){
            @Override
            public String answer(InvocationOnMock invocation) {
                String arg = invocation.getArgumentAt(0, String.class);
                System.out.println(arg);
                if (arg.equals("bio")) {
                    return "";
                }
                return person.getInfo(arg); // defaul value for firstName
            }});

        try {
            new Student(mockedPerson);
            fail();
        } catch (MultilingualException e) {
            Mockito.reset(mockedPerson); // not sure if this works
            assertEquals(e.getMessage(), "message here");
        }
    }
}

予想通りしかし、それは動作しません。myTest1成功した最初の入力されたif文を。しかし、その後にmyTest2、第二ifの文を逃しています。@Override以下不思議なことのすべてがmyTest2逃し、すぐにそのに移行しますcatch

私はまた、個々の嘲笑のインスタンスを作成しようとしたPersonが、それはまだ同じカバレッジ結果を持っています。

どのようにして、2つの連続した試験とカバーするifのと同じ方法で評価値を取得し、コンストラクタ内の文を?

編集します

私は以下の最も簡単な方法を試してみましたが、それはそう.when第二の試験はまだ最初のトリガので、引数の値が何であるかを気にしませんif

@Test(expected=SomethingError.class)
public void test() throws SomethingError {
    Mockito.when(mockedPerson.getInfo("firstName")).thenReturn(null);
    try {
        new Student(mockedPerson);
    } catch (SomethingError e) {
        assertEquals(e.getMessage(), "message here");
    }
}

@Test(expected=SomethingError.class)
public void test2() throws SomethingError {
    Mockito.when(mockedPerson.getInfo("bio")).thenReturn(null);
    try {
        new Student(mockedPerson);
    } catch (SomethingError e) {
        assertEquals(e.getMessage(), "message here");
    }
}
A4L:

そのための必要はありませんprivate Student student;、actualyあなたのテストクラスのそれらのフィールドのすべてを取り除くことができ、あなたのテストでは、可能な限り独立したとしてもsould、そしてあなたのケースでは、あなたはモックを行うことができ、それぞれの試験方法でalltoghetherをstubing。使用する

ArgumentMatchers.eq("firstName");

あなたの引数の値の平等をチェックするために、また、あなたがしたい場合は、回答バリアントを使用しますが、あなたはこれを小文字にすることは非常に簡単であることがあります。

ここでは、あなたのテストは、ように見えることができるかです:

@Test
public void newStudentWithPersonWithNullFirstName() {

    Person person = Mockito.mock(Person.class);

    Mockito
        .doReturn(null)
        .when(person)
        .getInfo(ArgumentMatchers.eq("firstName"));

    SomethingError actual = Assert
            .assertThrows(SomethingError.class, () -> new Student(person));
    Assert.assertEquals("firstName is null or empty", actual.getMessage());
}

@Test
public void newStudentWithPersonWithEmptyFirstName() {

    Person person = Mockito.mock(Person.class);

    Mockito
        .doReturn("")
        .when(person)
        .getInfo(ArgumentMatchers.eq("firstName"));

    SomethingError actual = Assert
            .assertThrows(SomethingError.class, () -> new Student(person));
    Assert.assertEquals("firstName is null or empty", actual.getMessage());
}

@Test
public void newStudentWithPersonWithNullBio() {

    Person person = Mockito.mock(Person.class);

    Mockito
        .doReturn("Foo")
        .when(person)
        .getInfo(ArgumentMatchers.eq("firstName"));

    Mockito
        .doReturn(null)
        .when(person)
        .getInfo(ArgumentMatchers.eq("bio"));

    SomethingError actual = Assert
            .assertThrows(SomethingError.class, () -> new Student(person));
    Assert.assertEquals("bio is null or empty", actual.getMessage());
}

@Test
public void newStudentWithPersonWithEmptyBio() {

    Person person = Mockito.mock(Person.class);

    Mockito
        .doReturn("Foo")
        .when(person)
        .getInfo(ArgumentMatchers.eq("firstName"));

    Mockito
        .doReturn("")
        .when(person)
        .getInfo(ArgumentMatchers.eq("bio"));

    SomethingError actual = Assert
            .assertThrows(SomethingError.class, () -> new Student(person));
    Assert.assertEquals("bio is null or empty", actual.getMessage());
}

@Test
public void newStudentWithPersonSuccess() {

    Person person = Mockito.mock(Person.class);

    Mockito
        .doReturn("Foo")
        .when(person)
        .getInfo(ArgumentMatchers.eq("firstName"));

    Mockito
        .doReturn("Bar")
        .when(person)
        .getInfo(ArgumentMatchers.eq("bio"));

    Student actual = new Student(person);
    Assert.assertEquals("Foo", actual.getCopyFirstName());
    Assert.assertEquals("Bar", actual.getOtherInfo());
}

カバレッジ:

ここでは、画像の説明を入力します。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=371039&siteId=1