MST

星途 面试题库

面试题:Java中接口与抽象类单元测试的区别

在Java中,接口和抽象类都有各自的特性。请阐述在对接口和抽象类进行单元测试时,测试策略和重点分别有哪些不同?以Junit为例,说明如何为接口和抽象类编写有效的单元测试代码。
19.8万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

测试策略和重点的不同

  1. 接口
    • 测试策略:接口本身不能被实例化,测试时需通过实现该接口的类来间接测试接口方法。通常采用针对接口的不同实现类分别进行测试,以验证每个实现类对接口契约的遵循情况。
    • 测试重点:验证实现类是否正确实现了接口中定义的所有方法,确保方法签名、返回值类型和行为符合接口定义。关注接口方法的功能性,例如输入不同参数时,方法是否返回预期结果。同时检查实现类在实现接口方法过程中,对异常情况的处理是否符合接口的隐含或明确规定。
  2. 抽象类
    • 测试策略:由于抽象类不能被实例化,但可以包含具体方法和抽象方法。测试时需创建抽象类的具体子类来测试其具体方法。对于抽象方法,需检查子类是否正确重写。
    • 测试重点:对于抽象类的具体方法,重点测试其功能逻辑是否正确。对于抽象方法,要验证子类重写后的行为是否符合抽象类设计的预期。同时关注抽象类中可能存在的受保护方法和字段,测试它们在子类继承后的访问和使用是否合理。还要测试抽象类中对继承和多态机制的支持,例如子类调用抽象类的具体方法时,是否能正确利用抽象类中的上下文和逻辑。

以Junit为例编写单元测试代码

  1. 接口的单元测试 假设存在一个接口 Calculator
public interface Calculator {
    int add(int a, int b);
}

实现类 SimpleCalculator

public class SimpleCalculator implements Calculator {
    @Override
    public int add(int a, int b) {
        return a + b;
    }
}

Junit测试代码:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class CalculatorTest {
    @Test
    public void testAdd() {
        Calculator calculator = new SimpleCalculator();
        int result = calculator.add(2, 3);
        assertEquals(5, result);
    }
}
  1. 抽象类的单元测试 假设存在一个抽象类 Shape
public abstract class Shape {
    public double getArea() {
        // 这里可以有通用逻辑,比如某些形状面积计算的公共部分
        return 0;
    }

    public abstract double getPerimeter();
}

具体子类 Circle

public class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }

    @Override
    public double getPerimeter() {
        return 2 * Math.PI * radius;
    }
}

Junit测试代码:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class ShapeTest {
    @Test
    public void testCircleArea() {
        Shape circle = new Circle(5);
        assertEquals(25 * Math.PI, circle.getArea(), 0.0001);
    }

    @Test
    public void testCirclePerimeter() {
        Shape circle = new Circle(5);
        assertEquals(10 * Math.PI, circle.getPerimeter(), 0.0001);
    }
}