Junit testing - Initialization Exception error - java

//registry Class
public class Registry
{
private static final Logger logger = LogFactory
.getLogger(Registry.class);
protected Service service = new serviceMLImpl();
private static Registry instance = new Registry();
public static Registry getInstance()
{
return instance;
}
public static void setInstance(Registry instance)
{
Registry.instance = instance;
}
public Helper getHelper()
{
return new Helper();
}
}
//Helper Class
public class Helper
{
protected Service service = ServiceRegistry
.getService();
public Helper()
{
}
public void sendInfo(Info info)
throws Exception
{
service.sendInfo(info);
}
public void sendFacilitySFPListNotification(
List<GcpFacilitySFPInfo> esfpPortList)
{
gfpGcpService.sendFacilitySFPListNotification(esfpPortList);
}
}
//Test Class
public class RegistryTest
{
Registry registry = new Registry();
Helper helper = createMock(Helper.class);
#Before
public void setUp() throws Exception
{
}
#After
public void tearDown() throws Exception
{
registry = null;
}
#Test
public void testGetInstance()
{
replayAll();
registry.getInstance();
verifyAll();
}
#Test
public void testSetInstance()
{
replayAll();
registry.setInstance(registry);
verifyAll();
}
#Test
public void testGetHelper()
{
**replayAll();
new Helper();
registry.getHelper(); // getting InitializationExceptionError here
verifyAll();** //
}
}
Two classes are there, Helper and Registry class. I tried to write the junit for registry class but got InitializationException in the test class.
This is the error i am getting at registry.getHelper():
java.lang.ExceptionInInitializerError at java.lang.Class.forName0(Native Method) at
java.lang.Class.forName(Class.java:169) at
javassist.runtime.Desc.getClassObject(Desc.java:44) at
javassist.runtime.Desc.getClassType(Desc.java:153) at
javassist.runtime.Desc.getType(Desc.java:123) at
javassist.runtime.Desc.getType(Desc.java:79) at
com.att.bbnms.cim.gfpgcp.service.ServiceRegistry.getService(ServiceRegistry.java‌​:41) at
com.att.bbnms.cim.nc.service.link.Helper.(Helper.java:14) at
com.att.bbnms.cim.nc.service.link.Registry.getHelper(Registry.java:26) at
com.att.bbnms.cim.nc.service.link.egistryTest.testGetHelper(RegistryTest.java:63‌​) at
org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66) at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$Po‌​werMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:‌​312) at
org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86) at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadi‌​e.java:94) at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$Po‌​werMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:29‌​6) at
Also while writing the test case for Helper , I am not able to get in the class.
Please tell if you have any solution.

Related

#ExtendWith getting executed in every test class, rather than only once

I am trying to create extensions A_Extension and B_Extension, which will get executed only once at start and at the end of all test classes.
Where as, I want to call C_Extension always in each test class.
Here are my extensions and test classes.
public class A_Extension implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {
private static boolean isInitialized = false;
#Override
public void beforeAll(ExtensionContext context) throws Exception {
if (!isInitialized) {
//Do something and return ABC
isInitialized = true;
context.getRoot().getStore(GLOBAL).put("ABC", ABC);
}
}
#Override
public void close() throws Throwable {
ABC = null;
}
}
public class B_Extension implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {
private static boolean isInitialized = false;
#Override
public void beforeAll(ExtensionContext context) throws Exception {
if (!isInitialized) {
//Do something and return PQR
isInitialized = true;
context.getRoot().getStore(GLOBAL).put("PQR", PQR);
}
}
#Override
public void close() throws Throwable {
PQR = null;
}
}
public class C_Extension implements AfterEachCallback, AfterAllCallback, BeforeAllCallback {
//some extension code
}
#ExtendWith({A_Extension.class,B_Extension.class})
class TestClass1 {
#RegisterExtension
static C_Extension cExtension = new C_Extension();
#BeforeAll
static void beforeAllClass() { }
#AfterAll
static void afterAllClass() { }
#Test
void case1() { }
#Test
void case2() { }
}
#ExtendWith({A_Extension.class,B_Extension.class})
class TestClass2 {
#RegisterExtension
static C_Extension cExtension = new C_Extension();
#BeforeAll
static void beforeAllClass() { }
#AfterAll
static void afterAllClass() {}
#Test
void case1() {}
#Test
void case2() {}
}
But A_Extension.class and B_Extension.class are getting called always in each test case.
What can be the reason behind this?

Mockito, MissingMethodInvocationException when run all tests in class

Here is my test class.
#ExtendWith(MockitoExtension.class)
class DishServiceTest {
static MockedStatic<DaoFactory> daoFactoryDummy;
static MockedStatic<FileUtil> fileUtilDummy;
#Mock
DaoFactory daoFactory;
#Mock
DishDao dishDao;
#Spy
DishService dishService;
#BeforeAll
static void setUp() {
fileUtilDummy = Mockito.mockStatic(FileUtil.class);
daoFactoryDummy = Mockito.mockStatic(DaoFactory.class);
}
#AfterAll
static void close() {
daoFactoryDummy.close();
fileUtilDummy.close();
}
#Test
void deleteWithImage_id0_success() {
daoFactoryDummy.when(ServiceManager::getInstance).thenReturn(daoFactory);
when(daoFactory.createDishDao()).thenReturn(dishDao);
long id = 2;
String deleteDir = "/dish-image/2";
dishService.deleteWithImage(id, deleteDir);
verify(dishDao, times(1)).delete(id);
fileUtilDummy.verify(() -> FileUtil.deleteDishFolder(deleteDir));
}
#Test
void update_idSet_success() {
daoFactoryDummy.when(ServiceManager::getInstance).thenReturn(daoFactory);
when(daoFactory.createDishDao()).thenReturn(dishDao);
Dish dish = new Dish(2, "testName",
"testDescription", Category.DRINKS, BigDecimal.TEN, "/image21");
dishService.saveOrUpdate(dish);
verify(dishDao, times(1)).update(dish);
verify(dishDao, times(1)).close();
}
}
I mock static methods like this because DishService class gets dao object from DaoFactory.
Here is an example of DishService method
public class DishService {
public void saveOrUpdate(Dish newDish) {
try (DishDao dishDao = DaoFactory.getInstance().createDishDao()) {
long newDishId = newDish.getId();
if (newDishId == 0) {
dishDao.save(newDish);
} else {
dishDao.update(newDish);
}
}
}
}
And of DaoFactory
public class JDBCDaoFactory extends DaoFactory {
DBManager dbManager = DBManager.getInstance();
UserDaoMapper userDaoMapper = new UserDaoMapper();
DishDaoMapper dishDaoMapper = new DishDaoMapper();
OrderDaoMapper orderDaoMapper = new OrderDaoMapper();
OrderItemDaoMapper orderItemDaoMapper = new OrderItemDaoMapper();
#Override
public UserDao createUserDao() {
return new JDBCUserDao(dbManager.getConnection(),
userDaoMapper);
}
#Override
public DishDao createDishDao() {
return new JDBCDishDao(dbManager.getConnection(), dishDaoMapper);
}
#Override
public OrderDao createOrderDao() {
return new JDBCOrderDao(dbManager.getConnection(), orderDaoMapper,
orderItemDaoMapper);
}
}
And here is the exception I have
org.mockito.exceptions.misusing.MissingMethodInvocationException:
Also, this error might show up because:
you stub either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified. Mocking methods
declared on non-public parent classes is not supported.
inside when() you don't call method on mock but on some other object. at
service.DishServiceTest.update_idSet_success(DishServiceTest.java:61)
Here is the line 61
The strangest thing here is that tests pass when I run them seperately, but if i press run all tests in class I get the exception above.

How to inject mocks into a class that has 1 constructor with parameters?

I have the following class (Condensed it to focus on issue instead of showing entire class):
#Component
public class ABCDEF {
private final Helper helper;
private final URI uri;
public ABCDEF(Helper helper, #Value("${endpoint.url}") URI uri) {
this.helper = helper;
this.uri = uri;
}
public void b(){
helper.toString();
}
}
For its test, I am looking to inject the mocks as follows but it is not working.
The helper comes up as null and I end up having to add a default constructor to be able to throw the URI exception.
Please advice a way around this to be able to properly inject the mocks. Thanks.
#RunWith(JUnitMockitoRunner.class)
public class ABCDEFTest {
#Mock
private Helper helper;
#InjectMocks
private ABCDEF abcdef = new ABCDEF(
helper,
new URI("test")
);
// adding just to be able to throw Exception
public ABCDEFTest() throws URISyntaxException {
}
#Test
public void b() {
abcdef.b();
}
}
Note: Using Mockito version 1.10.19. Will need to stick to this version.
This should work:
#RunWith(MockitoJUnitRunner.class)
public class ABCDEFTest {
#Mock
private Helper helper;
private ABCDEF abcdef;
#Before
public void setUp() throws URISyntaxException {
abcdef = new ABCDEF(
helper,
new URI("test")
);
}
#Test
public void b() {
abcdef.b();
}
}
Or, instead of using #RunWith, you can initialize mock inside setUp method:
public class ABCDEFTest {
private Helper helper;
private ABCDEF abcdef;
#Before
public void setUp() throws URISyntaxException {
helper = Mockito.mock(Helper.class);
abcdef = new ABCDEF(
helper,
new URI("test")
);
}
#Test
public void b() {
abcdef.b();
}
}

JUnit to TestNG - #Rule in Superclass

I'm converting from JUnit to TestNG and facing a issue moving away from the #Rule annotation in JUnit.
In my superclass there is a #Rule, when I change this to #BeforeMethod it simply does not go into that method. (using that Println to confirm)
Also, when i do simply change #Rule or #ClassRule to #BeforeMethod, Eclipse complains that it is 'disallowed at this location'.
(Note I've removed some methods in the below to make the code length a little shorter/easier to view).
public abstract class AbstractTests
{
protected static boolean oneTimeSetUpComplete;
private static Logger log;
private static WebSessionFactory sessionFactory;
private static WcConfigManager config;
private WebSession session;
TestLogger testLogger = new TestLogger(getConfig(), getLog());
private StringBuilder errors = new StringBuilder();
protected WteDataProvider data;
#ClassRule
public static ExternalResource mainConfiguration = new ExternalResource() {
protected void before() throws Throwable {
setUpTests();
};
};
public Verifier errorCollector = new Verifier(){
#Override
protected void verify() throws Throwable {
failTestIfThereAreErrors();
};
};
public TestLogger getTestLogger() {
return testLogger;
}
#Rule
public RuleChain executionOrder() {
return RuleChain.outerRule(getTestLogger()).around(errorCollector);
}
#Rule
public TestRule dataReader = new TestRule() {
public Statement apply(final Statement base,
final Description description) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
System.out.println("PRINT IF YOU GO IN HERE");
DataProvider dataProvider = description.getAnnotation(DataProvider.class);
if (dataProvider == null) {
dataProvider = description.getTestClass().getAnnotation(DataProvider.class);
}
base.evaluate();
};
};
};
};
protected AbstractArgosTests(
Logger logger,
WcConfigManager configManager,
WebSessionFactory factory)
{
setUpTests(logger, configManager, factory);
}
}

Running two same tests with different arguments

I have a test with 15-20 different test cases, I want to run the same test with twice with two different parameters which are supposed to be passed to the test's BeforeClass method, for instance:
public class TestOne {
private static ClassToTest classToTest;
#BeforeClass
public static void setUp() throws Exception {
classToTest = new ClassToTest("Argument1", "Argument2");
}
#Test
public void testOne() {
........roughly 15 - 20 tests here
}
public class TestTwo {
private static ClassToTest classToTest;
#BeforeClass
public static void setUp() throws Exception {
classToTest = new ClassToTest("Argument3", "Argument4");
}
#Test
public void testOne() {
........roughly 15 - 20 tests here, same as in TestOne
}
As you can see the only difference between these two tests is in the setup method, which passes different values to the constructor of the ClassToTest. I don't want to replicate the test methods in both classes, but would prefer either inheritance or some other intelligent way to achieve this in one class.
This seems like a perfect use case for JUnit4's #Parameters; see https://blogs.oracle.com/jacobc/entry/parameterized_unit_tests_with_junit or http://www.mkyong.com/unittest/junit-4-tutorial-6-parameterized-test/ . That said, you'll have to move the initialization from the setUp method to a constructor for the test class.
For what it's worth, here is how you would do it with TestNG:
public class TestFactory {
#Factory
public Object[] createTests() {
return new Object[] {
new ClassToTest("arg1", "arg2"),
new ClassToTest("arg3", "arg4")
};
}
}
public class ClassToTest {
public ClassToTest(String arg1, String arg2) {
this.arg1 = arg1;
this.arg2 = arg2;
}
#Test
public void testOne() {
// use arg1 and arg2
}
}
Thanks all for your quick replies. This is how I did it finally
public abstract class Base {
final HeavyObject heavy;
protected Base(HeavyObject heavy) {
this.param = param;
}
#Test
public void test() {
param.doSomething();
}
#Test
.............More tests here
}
public class FirstTest extends Base{
private static HeavyObject param;
#BeforeClass
public static void init() {
param = new HeavyObject("arg1", "arg2");
}
public FirstTest() {
super(param);
}
}
public class SecondTest extends Base{
private static HeavyObject param;
#BeforeClass
public static void init() {
param = new HeavyObject("arg3", "arg4");
}
public FirstTest() {
super(param);
}
}
Base is an abstract class which has all the tests and FirstTest and SecondTest create their own objects with different parameters and pass it to the abstract class to use it.
As per the documentation (http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html):
A subclass does not inherit the private members of its parent class.
However, if the superclass has public or protected methods for
accessing its private fields, these can also be used by the subclass.
How about this:
public class TestOne {
private static ClassToTest classToTest1, classToTest2;
#BeforeClass
public static void setUp() throws Exception {
classToTest1 = new ClassToTest("Argument1", "Argument2");
classToTest2 = new ClassToTest("Argument3", "Argument4");
}
#Test
public void testOne() {
testOneImpl(classToTest1);
testOneImpl(classToTest2);
}
public void testOneImpl(ClassToTest classToTest) {
// exact samew as whatever your current testOne() test method is
}
....
}
EDIT:
Or to keep method count down:
public class TestOne {
private static List<ClassToTest> classesToTest;
#BeforeClass
public static void setUp() throws Exception {
classesToTest = new ArrayList<>;
classesToTest.add( new ClassToTest("Argument1", "Argument2"));
classesToTest.add( new ClassToTest("Argument3", "Argument4"));
}
#Test
public void testOne() {
for (ClassToTest classToTest: classesToTest) {
... same test content as before
}
}

Categories

Resources