JMockit - 要测试的 class 实例为空
JMockit - Instance of class to be tested is null
所以我开始使用 JMockit 和 JUnit 来测试我的代码。
我写了一个 class 并想测试那个 class。 class如下-
public final class KingdomDAOImpl implements KingdomDAO {
private Map<KingdomType, Kingdom> kingdomEmblemMap;
@Inject
public KingdomDAOImpl(final Map<KingdomType, Kingdom> kingdomEmblemMap) {
this.kingdomEmblemMap = kingdomEmblemMap;
}
@Override
public Map<KingdomType, Kingdom> getKingdoms() {
return kingdomEmblemMap;
}
}
我的测试 class 看起来像这样 -
public class KingdomDAOTest {
@Injectable
private static Map<KingdomType, Kingdom> kingdomEmblemMap;
@Tested
private static KingdomDAOImpl kingdomDAO;
@BeforeClass
public static void beforeClass() {
kingdomEmblemMap = new HashMap<>();
}
@Test
public void getKingdomsTest() {
System.out.println("=========+> " + kingdomDAO);
final Map<KingdomType, Kingdom> actualKingdomEmblemMap = kingdomDAO.getKingdoms();
Assert.assertEquals(kingdomEmblemMap, actualKingdomEmblemMap);
}
}
现在,我遇到的问题是 kingdomDAO
实例是 null
,我无法理解为什么。因此,kindomDAO.getKingdoms()
抛出 NullPointerException
.
关于如何从这里开始的任何想法?
编辑:我使用的是 JMockit 版本 1.8
。我已尝试升级到 1.45
并将 @Injectable
注释替换为 @Tested
,但同样的问题仍然存在。
自从我上次使用它以来,JMockit 发生了一些变化。
我可以向您推荐的是,请务必阅读发行说明!
版本 1.42
JMockit now requires the use of the "-javaagent" JVM initialization
parameter
版本 1.45
Mocking annotations (@Mocked, @Capturing, and @Injectable) can no
longer be used on Java SE collection and map interfaces, for two
reasons: 1) on Java 8+, such interfaces include default methods, which
do get mocked, easily causing unexpected results in tests; 2) mocking
of said interfaces (and more generally, of all value-oriented types
which basically encapsulate state without complex behavior in methods)
is a well known bad practice. In the particular case of having an
@Injectable collection/map field which is meant to be injected into a
@Tested object, the test should be changed to use @Tested as well on
the collection/map field, with its declaration positioned before the
target @Tested field.
尽管我不会编写这样的测试代码,但工作示例是:
public class KingdomDAOtest {
@Tested
Map<KingdomType, Kingdom> kingdomEmblemMap = new HashMap<>();
@Tested
KingdomDAOImpl kingdomDAO;
@Test
public void getKingdomsTest() {
System.out.println("=========+> " + kingdomDAO);
final Map<KingdomType, Kingdom> actualKingdomEmblemMap = kingdomDAO.getKingdoms();
Assert.assertEquals(kingdomEmblemMap, actualKingdomEmblemMap);
}
}
所以我开始使用 JMockit 和 JUnit 来测试我的代码。
我写了一个 class 并想测试那个 class。 class如下-
public final class KingdomDAOImpl implements KingdomDAO {
private Map<KingdomType, Kingdom> kingdomEmblemMap;
@Inject
public KingdomDAOImpl(final Map<KingdomType, Kingdom> kingdomEmblemMap) {
this.kingdomEmblemMap = kingdomEmblemMap;
}
@Override
public Map<KingdomType, Kingdom> getKingdoms() {
return kingdomEmblemMap;
}
}
我的测试 class 看起来像这样 -
public class KingdomDAOTest {
@Injectable
private static Map<KingdomType, Kingdom> kingdomEmblemMap;
@Tested
private static KingdomDAOImpl kingdomDAO;
@BeforeClass
public static void beforeClass() {
kingdomEmblemMap = new HashMap<>();
}
@Test
public void getKingdomsTest() {
System.out.println("=========+> " + kingdomDAO);
final Map<KingdomType, Kingdom> actualKingdomEmblemMap = kingdomDAO.getKingdoms();
Assert.assertEquals(kingdomEmblemMap, actualKingdomEmblemMap);
}
}
现在,我遇到的问题是 kingdomDAO
实例是 null
,我无法理解为什么。因此,kindomDAO.getKingdoms()
抛出 NullPointerException
.
关于如何从这里开始的任何想法?
编辑:我使用的是 JMockit 版本 1.8
。我已尝试升级到 1.45
并将 @Injectable
注释替换为 @Tested
,但同样的问题仍然存在。
自从我上次使用它以来,JMockit 发生了一些变化。
我可以向您推荐的是,请务必阅读发行说明!
版本 1.42
JMockit now requires the use of the "-javaagent" JVM initialization parameter
版本 1.45
Mocking annotations (@Mocked, @Capturing, and @Injectable) can no longer be used on Java SE collection and map interfaces, for two reasons: 1) on Java 8+, such interfaces include default methods, which do get mocked, easily causing unexpected results in tests; 2) mocking of said interfaces (and more generally, of all value-oriented types which basically encapsulate state without complex behavior in methods) is a well known bad practice. In the particular case of having an @Injectable collection/map field which is meant to be injected into a @Tested object, the test should be changed to use @Tested as well on the collection/map field, with its declaration positioned before the target @Tested field.
尽管我不会编写这样的测试代码,但工作示例是:
public class KingdomDAOtest {
@Tested
Map<KingdomType, Kingdom> kingdomEmblemMap = new HashMap<>();
@Tested
KingdomDAOImpl kingdomDAO;
@Test
public void getKingdomsTest() {
System.out.println("=========+> " + kingdomDAO);
final Map<KingdomType, Kingdom> actualKingdomEmblemMap = kingdomDAO.getKingdoms();
Assert.assertEquals(kingdomEmblemMap, actualKingdomEmblemMap);
}
}