我目前正在通过Java教程进行学习,向我介绍抽象类并使用J-Unit进行测试。
我有2个文件,即AthleteTest和BikerTest,其中BikerTest扩展了AthleteTest.AthleteTest包含我不同测试的通用方法和变量,而BikerTest包含详细信息。
运动员
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public abstract class AthleteTest
{
private Athlete a1;
private Athlete a2;
protected String _name = "Test Athlete";
protected int _age = 32;
protected int _racerId = 987654;
public abstract Athlete getAthlete();
public abstract Athlete getExplicitAthlete();
public AthleteTest()
{
a1 = getAthlete();
a2 = getExplicitAthlete();
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testConstructors()
{
assertNotNull("Default Runner could not be created", a1);
assertNotNull("Explicit Runner could not be created", a2);
assertEquals("Name not set correctly on a2"
, _name
, a2.getName());
assertEquals("Age not set correctly on a2"
, _age
, a2.getAge());
assertEquals("RacerID not set correctly on a2"
, _racerId
, a2.getRacerId());
}
@Test
public void testGetSetName()
{
a1.setName(_name);
assertEquals("The name could not be set as expected"
, _name
, a1.getName());
}
@Test
public void testGetSetAge()
{
a1.setAge(_age);
assertEquals("The age could not be set as expected"
, _age
, a1.getAge());
}
@Test
public void testGetSetRacerId()
{
a1.setRacerId(_racerId);
assertEquals("The racerId could not be set as expected"
, _racerId
, a1.getRacerId());
}
public abstract void testPerformRaceActivity();
@Test
public void testToString()
{
a1.setName(_name);
a1.setAge(_age);
a1.setRacerId(_racerId);
String rts = a1.toString();
assertTrue("To String does not contain name"
, rts.contains(_name));
assertTrue("To String does not contain age"
, rts.contains(String.format("%d", _age)));
assertTrue("To String does not contain racer id"
, rts.contains(String.format("%d", _racerId)));
String rc = a1.getClass().toString();
assertTrue("To String does not contain class"
, rts.contains(rc));
}
}
自行车赛
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class BikerTest extends AthleteTest
{
private Biker r;
private String raceActivity = "Biking";
private boolean usesClips = false;
@Override
public Athlete getAthlete() {
return new Biker();
}
@Override
public Athlete getExplicitAthlete() {
return new Biker(_name,_age,_racerId,usesClips);
}
@Before
public void setUp()
{
r = new Biker();
}
@After
public void tearDown()
{
r = null;
}
@Test
public void testConstructors()
{
super.testConstructors();
Biker r2 = new Biker(_name, _age, _racerId, usesClips);
assertNotNull("Explicit Biker could not be created", r2);
assertEquals("Name not set correctly on R2"
, _name
, r2.getName());
assertEquals("Age not set correctly on R2"
, _age
, r2.getAge());
assertEquals("RacerID not set correctly on R2"
, _racerId
, r2.getRacerId());
assertEquals("UsesClips not set correctly on R2"
, usesClips
, r2.getUsingClips());
}
@Test
public void testGetSetUsingClips()
{
r.setUsingClips(usesClips);
assertEquals("The clips could not be set as expected"
, usesClips
, r.getUsingClips());
}
@Test
public void testPerformRaceActivity()
{
String pra = r.performRaceActivity();
assertTrue("Perform race activity did not contain activity"
, pra.contains(raceActivity));
}
@Test
public void testToString()
{
super.testToString();
r.setName(_name);
r.setAge(_age);
r.setRacerId(_racerId);
r.setUsingClips(usesClips);
String rts = r.toString();
assertTrue("To String does not contain using clips"
, rts.contains(String.format("%b", usesClips)));
assertTrue("To string does not contain performRaceActivity"
, rts.contains(raceActivity));
}
}
现在,虽然我的文件和代码正在工作(取自提供的示例),但由于教程没有详细介绍如何执行测试,因此我无法弄清其为何起作用。
QN1
为什么我在抽象类AthleteTest中需要构造函数?我的理解是,由于它是抽象的,因此不会被实例化,因此不需要构造函数,因为构造函数仅在实例化该类时起作用。
QN2
测试如何进行?测试顺序是怎样的?例如,当我运行BikerTest时,虽然我覆盖了GetAthlete和GetExplicitAthlete类,但实际上并没有运行代码中的方法。但是为什么当我运行代码时却运行了这些方法。默认情况下,JUnit是否只运行所有方法?
QN3
运行BikerTest时,超类AthleteTest如何实例化和工作?例如,在BikerTest中,我调用了super-这是AthleteTest.AthleteTest是在我调用super时实例化/创建的-生成的对象存储在a1和a2中,或者它是在某个时间和某个地方创建的其他?
预先感谢您提供的任何澄清和解释!
最佳答案
为什么我在抽象类AthleteTest中需要构造函数?
理解是因为它是抽象的,所以不会
实例化,因此不需要构造函数,因为
构造函数仅在实例化该类时起作用。
抽象类不能直接实例化-它们必须由非抽象类进行子类化,并且可以实例化该子类。但是,当实例化一个子类时,超类的所有字段也都是您创建的对象的一部分。并且,抽象超类的构造函数也被调用。
测试如何进行?测试顺序是怎样的?对于
例如,当我运行BikerTest时,我覆盖了GetAthlete和
GetExplicitAthlete类,我实际上并未在
code.Yet为什么在我运行代码时会运行方法。是否
JUnit默认情况下只是运行所有方法?
当使用JUnit 4将类作为测试运行时,所有带有@Test注释的方法都将作为测试方法运行。用@Before注释的方法在每次测试运行之前运行,用@After注释的方法在每次测试之后运行。
您可以使用更多注释,例如@BeforeClass和@AfterClass。
我跑步时超类AthleteTest如何实例化和工作
BikerTest?例如,在BikerTest中,我调用了super-
AthleteTest.Ith实例化/创建的AthleteTest
调用super-并将结果对象存储在a1和a2中,
还是在某个时候和其他地方创建的?
不,在实例化子类时将实例化超类。实际上,您创建了一个对象,该对象包含您实例化的子类中的所有字段及其所有超类。因此,当JUnit为您创建BikerTest
的实例时,AthleteTest
的所有字段(都是BikerTest
的超类,也是在对象的一部分中创建的。)还调用了AthleteTest
的构造函数。