Java实例化带父类构造参数的派生类对象 JUnit5 TDD测试问题求助
问题根因
你现在的报错和测试不通过有几个非常直观的低级错误,先修正:
- 你自定义的
GameAI类构造方法名写错了:类名是GameAI,构造方法写成了小写开头的gameAI,这会导致类没有合法的公开构造方法,编译阶段就有问题。 - 测试类里的对象类型写错了:你声明的
AIObject类型是GameAITest,这是你当前的测试类本身,你要实例化的是业务类GameAI。 - 你给
GameAI构造方法传入的info对象根本没有初始化,就是个空值,父类AI初始化的时候要调用info的方法,自然就报空指针。 - 测试类的
setUp方法连闭合的大括号都没写,编译不通过。
1. 尝试的方向完全错了吗?
方向完全没问题。TDD 对于游戏里的逻辑层、策略层代码(比如你要写的移动逻辑、决策逻辑)的帮助和其他业务开发场景没有区别,你遇到的问题都是单测基础配置和依赖处理的问题,和TDD本身无关。
2. 需要用JUnit动态测试吗?
完全不需要。JUnit动态测试适用于需要批量生成测试用例的场景,你当前的诉求是写基础单测,用普通的@Test注解就足够,没必要额外学习这部分内容。
3. 需要用Mockito等mock框架吗?
非常需要,这是解决你当前空指针问题最便捷的方案。你依赖的Info是游戏jar包提供的接口/类,你不需要关心它的真实实现,用Mockito可以直接Mock出一个Info的实例,还能自定义它所有方法的返回值,完全不需要启动游戏环境就能完成逻辑测试。
4. 可以直接实例化GameAI吗?需要用反射吗?
可以直接实例化,完全不需要反射。反射是游戏框架用来加载、初始化你的GameAI类用的,你自己写测试直接new GameAI(传入mock好的Info实例)就行,完全没必要自己写反射逻辑。
修正后的代码示例
第一步:修正GameAI类的构造方法
// 其他代码不变,只改构造方法名,首字母大写和类名保持一致 public GameAI(Info info) { super(info); setJerseyNumber(32); }
第二步:引入Mockito依赖
在你的项目构建工具(Maven/Gradle)中引入Mockito的JUnit5支持依赖即可。
第三步:修正后的测试类
package jimmy.kilmer.com; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.when; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import jarPackageImports.Info; // 开启Mockito注解支持 @ExtendWith(MockitoExtension.class) class GameAITest { // Mock出Info实例,不用自己实现 @Mock private Info info; private GameAI aiObject; @BeforeEach void setUp() throws Exception { // 给用到的方法打桩,按测试需求配置返回值 // 示例中设置screenWidth=1600、screenHeight=1300,计算后正好匹配你预期的80*65数组 when(info.getScreenWidth()).thenReturn(1600); when(info.getScreenHeight()).thenReturn(1300); // 父类要调用的getScene()提前打桩避免空指针,如果后续用到scene的其他方法,再mock Scene实例打桩即可 when(info.getScene()).thenReturn(null); // 直接实例化GameAI aiObject = new GameAI(info); } @AfterEach void tearDown() throws Exception { } @Test void testPopulateAllPossibleNodes() { // 1. given/arrange int[][] expected = new int[80][65]; // 2. when/act int[][] actual = aiObject.populateAllPossibleNodes(); // 3. then/assert assertArrayEquals(expected, actual); } }
上述代码就能跑通你当前的测试用例,后续写其他逻辑测试时,只要给info的对应方法打桩返回你需要的测试值即可。
内容的提问来源于stack exchange,提问作者drexl spivey
相关产品推荐
相关产品推荐

