单元测试mock

发布于:2025-03-19 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、背景

现在有A类,B类,C类,A类依赖B类,依赖C类,如果想要测试A类中的某个方法的业务逻辑。A类依赖其他类,则把其他类给mock,然后A类需要真实对象。这样就可以测试A类中的方法。

举例:Ticket类需要调用Flight类和Passenger类,需要测试Ticket类中的saleByAge()方法。我们只需mock 一下Flight类和Passenger类 ,实例化对象 Ticket类,并按照Ticket类的构造方法Ticket()传参。这样我们即使没有Flight类和Passenger类的代码,也可以测试Ticket类的方法。

二、被测试类Ticket.java的代码

package fit5171.monash.edu;
public class Ticket
{
    private int ticket_id;
    private int price;
    Flight flight;
    private boolean classVip; //indicates if this is bussiness class ticket or not
    private boolean status; //indicates status of ticket: if it is bought by someone or not
    Passenger passenger;

    public Ticket(int ticket_id,int price, Flight flight, boolean classVip, Passenger passenger)
    {
        this.ticket_id=ticket_id;
        this.price = price;
        this.flight = flight;
        this.classVip = classVip;
        this.status = false;
        this.passenger=passenger;
    }

    public Ticket() {

    }

    public int getTicket_id() {
        return ticket_id;
    }

    public void setTicket_id(int ticket_id) {
        this.ticket_id = ticket_id;
    }

    public int getPrice() { return price; }

    public void setPrice(int price)
    {
        this.price = price;
        saleByAge(passenger.getAge()); //changes price of the ticket according to the age category of passenger
        serviceTax( ); //changes price by adding service tax to the ticket
    }

    public void saleByAge(int age)
    {
        int price = getPrice();
        if(age < 15)
        {
            price-=(int)price*0.5;//50% sale for children under 15
            this.price=price;

        } else if(age>=60){
            this.price=0; //100% sale for elder people
        }
    }

    public Flight getFlight() {
        return flight;
    }

    public void setFlight(Flight flight) {
        this.flight = flight;
    }

    public boolean getClassVip() {
        return classVip;
    }

    public void setClassVip(boolean classVip) {
        this.classVip = classVip;
    }

    public boolean ticketStatus()
    {
        return status;
    }

    public void setTicketStatus(boolean status)
    {
        this.status = status;
    }

    public void serviceTax(){
        this.price *= 1.12;
    } //12% service tax

    public Passenger getPassenger() {
        return passenger;
    }

    public void setPassenger(Passenger passenger) {
        this.passenger = passenger;
    }

    public String toString()
    {
        return"Ticket{" +'\n'+
                "Price=" + getPrice() + "KZT, " + '\n' +
                getFlight() +'\n'+ "Vip status=" + getClassVip() + '\n' +
                getPassenger()+'\n'+ "Ticket was purchased=" + ticketStatus() + "\n}";
    }
}

三、测试Ticket类中的SaleByAge方法代码

package fit5171.monash.edu;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

class SaleByAgeTest {
    private Ticket ticket;
    private Flight mockFlight;
    private Passenger mockPassenger;

    @BeforeEach
    void setUp() {
        mockFlight=mock(Flight.class);
        mockPassenger=mock(Passenger.class);
        ticket=new Ticket(1,100, mockFlight, false, mockPassenger);
    }
    @Test
    void testSaleByAgeForChildren() {//儿童半折
        when(mockPassenger.getAge()).thenReturn(10);
        ticket.saleByAge(mockPassenger.getAge());//调用方法
        assertEquals(50,ticket.getPrice());
    }
    @Test
    void testSaleByAgeForelder() {//老年人免费
        when(mockPassenger.getAge()).thenReturn(70);
        ticket.saleByAge(mockPassenger.getAge());//调用方法
        assertEquals(0,ticket.getPrice());
    }
}

四、运行结果如下

五、pom.xml配置文件如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>dycs</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <!-- JUnit 5 API -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.10.0</version>
            <scope>test</scope>
        </dependency>
        <!-- JUnit 5 引擎 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.10.0</version>
            <scope>test</scope>
        </dependency>
        <!-- JUnit 平台引擎 -->
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-engine</artifactId>
            <version>1.10.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>4.8.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>2.0.9</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>2.0.9</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>5.2.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

六、注意事项

mock是模拟对象,是空实现。如果要实现具体的业务逻辑的单元测试,必须创建真实对象,真实对象中涉及到类,可以mock。

使用when指定行为的值,如指定mock乘客的年龄为10.

@Test
    void testSaleByAgeForChildren() {//儿童半折
        when(mockPassenger.getAge()).thenReturn(10);
        ticket.saleByAge(mockPassenger.getAge());//调用方法
        assertEquals(50,ticket.getPrice());
    }


网站公告

今日签到

点亮在社区的每一天
去签到