簡體   English   中英

我應該如何使用 Mockito 和 Junit 測試此方法?

[英]How should I test this method using Mockito and Junit?

假設有如下類:

CivilAddSystem class:

class CivilAddSystem{

    List<People> people = new ArrayList<>();
    List<Town> towns = new ArrayList<>();

    public People addPeople(People people) {
        people.add(people);
        return people;
    }

    public Town addTown(Town town) {
        towns.add(town);
        return town;
    }

    public House addHouse (House house, String townName) throws IllegalStateException {
        
        Town town = getTown(townName);
        if (null == town) throw new IllegalStateException("No matching town");

        town.addHouse(house);
        return house;
    }

public List<String> getTown(String name) {

        for (Town town : towns) {
            if (town.getName().equals(name)) return town;
        }

        return null;
    }
}

鎮class:

public class Town {
    List<House> houses = new ArrayList<>();

    String name;
    String abbreviation;

    public Town (String name, String abbreviation) {
      
        this.name = name;
        this.abbreviation = abbreviation;
    }
    
    public String getName() {
        return name;
    }
    
    public String getAbbreviation() {
        return abbreviation;
    }
    
    public void addHouse(House house) {
        houses.add(house);
    }
    
    public House getHouse(String unitNumber) {
        for (House house : houses) {
            if (house.getUnitNumber().equals(unitNumber)) return house;
        }

        return null;
    }
}

房子 class :

public class House {
    private final List<People> people = new ArrayList<>();

    private final String unitNumber;
    private final String houseName;

    public House (String unitNumber, String houseName) {

        this.unitNumber= unitNumber;
        this.houseName= houseName;
    }

    public String getUnitNumber() {
        return unitNumber;
    }

    public String getHouseName() {
        return houseName;
    }

    private People checkMovedInPeople(People person) {
        if (null == person) throw new NullPointerException();

        for (People movedIn : people) {
            if (movedIn.getName().equals(person.getName())) return movedIn;
            if (movedIn.getPersonID().equals(person.getPersonID())) return movedIn;
        }

        return null;
    }

    public void moveInPeople(People person) throws IllegalArgumentException, IllegalStateException {
         if (null == person) throw new IllegalArgumentException("Person shouldn't be null");
         if (null != checkMovedInPeople(person)) throw new IllegalStateException("Person is already in the house");

         people.add(person);
    }

    public List<String> getPeople() {
        List<String> results = new ArrayList<>();

        for (People person: people) {
            results.add(person.getPersonID());
        }

        return results;
    }

    public People getPerson(String match) {
        for (People person: people) {
            if (person.getPersonID().equals(match)) return person;
            if (person.getName().equals(match)) return person;
        }

        return null;
    }
}

而對於 class 人來說,它只有兩個變量:String PersonID 和 String Name 以及它們的 getter 方法。

所以,我想要實現的是,我目前正在嘗試在 CivilAddSystem class 中測試 addPeople 方法,並且我想使用 mockito 獨立測試它。

我使用 JUnit 編寫的測試用例是這樣的:

@Test
    public void testAddPeople() {
        CivilAddSystem CAS = new CivilAddSystem();
        Town town = CAS.addTown("BlueTown", "BT");
        House house = CAS.addHouse("U180", "BlueHouse", "BlueTown");
        People bob = CAS.addPeople("1", "Bob");
        Assert.assertEquals(CAS.getTown("BlueTown").getHouse("U180").getPerson("1"), null);

        house.moveInPeople(bob);
        Assert.assertEquals(CAS.getTown("BlueTown").getHouse("U180").getPerson("1").getPersonID, 1);
    }

但我真的很難為這個測試用例應用 mockito。

到目前為止我所做的只是 mocking Town、House 和 People 類,(不是 CivilAddSystem class,因為它是正在測試的),並停在那里......

誰能給我一個關於如何將 mockito 應用於上述測試用例的提示?

ps) 對上面的代碼進行一些修改是可以接受的(例如,應用依賴注入和類似的東西是可以接受的)。

提前致謝!

Mocking 使您能夠使 class看起來像另一個 class 或 ZA2F2ED4F8EBC2CBB4C21A29DC40AB6 匹配接口。 因此,如果您想測試 Town,您不想通過創建房屋來 go,您只需使用 Mockito 來模擬房屋。

理想情況下,Dwelling 將是一個接口,並且會有 House、TownHome、Condo、RanchHouse 等作為實現。 然后,當您測試 CivilAddSystem 時,您不會測試任何 TownHome 實現代碼。 您已將其隔離,因此您只是在測試一個 class。

所以你可以創建這樣的東西:

    // unit tests should only test one piece of functionality at a time.
    // This should only test the addition of a Person.  You should expect
    // to have lots of unit tests so that when one breaks, you can tell
    // exactly what broke
    @Test
    public void testAddTown() {
        Town mockedTown = Mockito.mock(Town.class);
        CivilAddSystem CAS = new CivilAddSystem();
        Town town = CAS.addTown(mockedTown);

        
        // verify that the town that was put in is the same as you get out...
        // note that you should not be testing the functionality of Town here
        // if you do, this breaks the isolation
        Assert.assertTrue(CAS.getTowns().contains(mockedTown));
    }

對於高級功能,您可以存根功能。 例如,如果您需要測試它是否是一個大城市,並且 CAS


    // checks this by determining if the population is > 100000
    @Test
    public void testAddTown() {
        Town mockedTown = Mockito.mock(Town.class);
        when(mockedTown.getPopulation()).thenReturn(100001)
        CivilAddSystem CAS = new CivilAddSystem();

        // verify that the current state is the expected state
        Assert.assertEquals(CAS.getNumberOfLargeTowns(), 0);
        // make a change
        Town town = CAS.addTown(mockedTown);
        // test that the updates state is as expected
        Assert.assertEquals(CAS.getNumberOfLargeTowns(), 1);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM