deallocating a variable in kotlin - junit

In kotlin, for writing tests, I have a guice injector created before each tests in the setUp phase and then I try to deallocate it in the tearDown phase:
class MyTestClass {
....
var injector: Injector? = null
...
#Before
fun setUp() {
...
injector = Guice.createInjector(modules)
...
}
#After
fun tearDown() {
...
injector = null
}
#Test
fun myFirstTest() {
myInstance = injector?.getInstance(Key.get(MyClass::class.java))
// use myInstance here
...
}
...
}
My question is that in Kotlin land, is such deallocation necessary at all? And if it is necessary, what is the best way to do it?

No, it's not necessary, and isn't even deallocation. All you're doing is rebinding injector to null. The old value is still hanging out in memory without a reference. Memory is cleaned up by the garbage collector when it deems appropriate.

Related

How to mock jdbcTemplate call of DAO class for Junit test

I have DAO class as below:-
// Here I have a class that creates it's own jdbcTemplate using new
// jdbcTemplate(dataSource)
#Repository
public class MyDao {
#Autowired
#Qualifier("db2JdbcTemplate)"
JdbcTemplate jdbcTemplateDB2;
public int insertTable(Company comp) {
int ret = 0;
try {
ret = this.jdbcTemplateDB2(db2DataSource).update(ïnsert into "+ table_name + "(COL1,COL2,...) values (?,?,?,..)",
ps-> {
ps.setString(1, comp.getName);
.......
});
return ret;
} catch (Exception ex) {
// log etc
}
}
}
My Test class is as below:-
#RunWith(MockitoJUnitRunner.class)
public class MyTest {
#Mock
JdbcTemplate jdbcTemplateDB2;
Company comp = new Company(); // this is followed by setter fn to set values.
MyDao mydao = Mockito.mock(MyDao.class);
Mockito.when(((jdbcTemplateDB2.update(any(String.class),
any(PreparedStatement.class))).thenReturn(2);
ReflectionUtils.setField(mydao, "jdbcTemplateDB2", jdbcTemplateDB2);
int bVal = mydao.insertTable(cmp);
}
}
iVal is not getting value 2. It is making original update call and returning value like 0/1.
Getting UnnecessaryStubbingException. If I make lenient() call the exception goes away but result is same (expected as lenient only removes warning).
How to make this stubbing work?
In this line: MyDao mydao = Mockito.mock(MyDao.class); you're creating a mock object, which overrides your actual class'x behavior, but you seem to want to test this very class, so it doesn't make any sense. What you need to do is: create an actual instance of the class and inject mocks into it (you're using ReflectionUtils to do that, but Mockito has it's own, simple mechanism to do that).
#Mock
JdbcTemplate jdbcTemplateDB2;
// this tells mockito to create the object and inject mocks into it
#InjectMocks
MyDao myDao;
#Test
void test() {
// define the behavior for the mock
when(jdbcTemplateDB2.update(...)).thenReturn(2);
// call the actual method of the tested class object (not a mock)
int result = myDao.insertTable(...);
// perform assertions (e.g. verify the result value)
}
Recommended reading: Mockito documentation (very comprehensive, yet simple).
Important note: field injection is discouraged.

How to use these #DataMongoTest and #SpringBootTest together in integration test

I am trying to write integration test case for one of my rest application which uses mongodb internally to persist the data
#DataMongoTest
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MainControllerTest {
#LocalServerPort
private int port = 8080;
/* some test cases*/
}
but I am getting below error
java.lang.IllegalStateException: Configuration error: found multiple declarations of #BootstrapWith for test class [com.sample.core.controller.MainControllerTest]: [#org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTestContextBootstrapper), #org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.context.SpringBootTestContextBootstrapper)]
looks like these two are mutually exclusive, so how to do the integration testing .
Use #AutoConfigureDataMongo with #SpringBootTest and this will resolve this ambiguity issue. #SpringBootTest and #DataMongoTest cannot be used together.
Answering to a very old post hoping it may help others.
#AutoConfigureDataMongo will connect to real database. In order to still use the embedded mongo, one can initiate the embedded mongoDb manually.
#SpringBootTest(classes = SubscriptionEventApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SubscriptionEventApiIntegrationTest {
#BeforeAll
static void setup() throws Exception {
startEmbeddedMongoDbManually();
}
private static void startEmbeddedMongoDbManually() throws IOException {
final String connectionString = "mongodb://%s:%d";
final String ip = "localhost";
final int port = 27017;
ImmutableMongodConfig mongodConfig = MongodConfig
.builder()
.version(Version.V3_5_5)
.net(new Net(ip, port, Network.localhostIsIPv6()))
.build();
MongodStarter starter = MongodStarter.getDefaultInstance();
mongodExecutable = starter.prepare(mongodConfig);
mongodExecutable.start();
mongoTemplate = new MongoTemplate(MongoClients.create(String.format(connectionString, ip, port)), "test");
}
#AfterAll
static void clean() {
mongodExecutable.stop();
}
#Test
public void test() {
.....
}
}
Purushothaman suggested starting embedded MongoDB server manually. I am suggesting to start it automatically using #DataMongoTest, but creating WebTestClient manually instead.
Kotlin code below, translates to Java trivially:
#DataMongoTest
// #ContextConfiguration may not be needed for your case.
#ContextConfiguration(
classes = [
Application::class,
MainController::class,
// Add more needed classes for your tests here.
// ...
]
)
#TestPropertySource(properties = ["spring.mongodb.embedded.version=4.0.12"])
class MainControllerTest(
#Autowired
private val mainController: MainController,
// Add more beans needed for your tests here.
// ...
) {
// Creating a WebTestClient is easy and
// can be done in different ways.
// Here is one of the possible ways.
private val webTestClient: WebTestClient =
WebTestClient.bindToController(mainController).build()
#Test
fun someTest() {
// ...
}
}

Mockito -mocking implementation class

Hi i am trying to mock dao layer
my application has some class hire achy like this Application->parser->dao(interface)->dao implementation class
my problem is when i am mocking dao interface or daoimp class using mockito
in my test case they are not working simply test case going to db how to do make our test case to use these mocked objects
#RunWith(MockitoJUnitRunner.class)
public class CsvDataLoadServiceImplTest {
#Mock private MeteringDataDao meteringDataDao;
List<Object> persistedList;
Object meteringData;
List<Object> s=new ArrayList<Object>();
#SuppressWarnings({ "rawtypes", "unchecked" })
#Before public void setup(){
Mockito.doAnswer(new Answer<List<Object>>() {
#Override
public List<Object> answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
System.out.println("persist all");
if(persistedList == null){
persistedList = (List)args[0];
}
else
persistedList.addAll((List)args[0]);
return null;
}}).when(meteringDataDao).persistAll(anyList());
Mockito.doAnswer(new Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
if(meteringData == null)
meteringData = (List)args[0];
return true;
}}).when(meteringDataDao).persist(anyObject());
}
#After public void tearDown(){
persistedList = null;
meteringData = null;
}
#Test
public void testDataAccuricy(){
CsvDataLoadService csvDataLoadService =new CsvDataLoadServiceImpl();
csvDataLoadService.loadRackspaceCsvData();
}
}
CsvDataLoadService csvDataLoadService = new CsvDataLoadServiceImpl();
You're constructing an instance of the service, but this instance doesn't use the DAO you mocked. It uses another one. You need something like
CsvDataLoadService csvDataLoadService =
new CsvDataLoadServiceImpl(meteringDataDao);
Your question is a little badly phrased, so sorry if I appear to have misunderstood you.
#JBNizet answer is correct, you're not using the mocked object, but rather than changing the code for a test you should simply change the test. This is always a best practice when writing your tests.
You haven't assigned the mocked object to the service, so I'm assuming that the MeteringDataDao object is actually instantiated inside the class you're attempting to test?
If so, then you will need something more powerful than Mockito (Unless you want to reproduce the capabilities of a more powerful already existing library). I would suggest PowerMockito, which I have used in the past for something exactly like this.
A good example of using powermockito to mock the constructor of a class can be seen in a few answers on SO already, so I'll just link to them rather than try and re-explain their already clear answers:
Powermock constructor mocking has no effect on the instantiated object
mockito mock a constructor with parameter

how to use DbUnit with TestNG

I need to integrate DbUnit with TestNG.
1) Is it possible to use DbUnit with TestNG as DbUnit is basically an extension of JUnit.
2) If yes how?
Finally i found out a way to use DbUnit with TestNG!
Using Instance of IDatabaseTester works,
but another work around would be :
To extend AbstractDatabaseTester and implement getConnection and override necessary functions.
But one important thing is to call onSetup() and onTeardown() before and after testing.
Hope this helps...
Not sure what you are trying to do exactly, but perhaps Unitils would be helpful. It is like a dbunit extension but not limited to that, and supports integration with TestNg (by extending UnitilsTestNG class for your testcase).
Here is simple class that performs the required function.
public class SampleDBUnitTest {
IDatabaseTester databaseTester;
IDataSet dataSet;
#BeforeMethod
public void setUp() throws Exception {
// These could come as parematers from TestNG
final String driverClass = "org.postgresql.Driver";
final String databaseUrl = "jdbc:postgresql://localhost:5432/database";
final String username = "username";
final String password = "password";
dataSet = new FlatXmlDataSet(Thread.currentThread().getContextClassLoader().getResourceAsStream("dataset.xml"));
databaseTester = new JdbcDatabaseTester(driverClass, databaseUrl, username, password);
databaseTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT);
databaseTester.setDataSet(dataSet);
databaseTester.setTearDownOperation(DatabaseOperation.NONE);
databaseTester.setDataSet(dataSet);
databaseTester.onSetup();
}
#AfterMethod
public void tearDown() throws Exception {
databaseTester.onTearDown();
}
#Test
public void t() throws Exception {
// Testing, testing
}
}

Mocking a dependency that is not visible outside

I have to unit test some old code that wasn't designed to support unit testing (No DI). Is there a way to mock an object that is being initialized within a public method?
public int method() {
A a = new A(ar1, arg2); //How to mock this?
}
Thanks,
-Abidi
Another option is to refactor the code into
public int method() {
A a = createA(arg1,arg2);
}
A createA(int arg1, int arg2) {
return new A(arg1,arg2);
}
In your test method now you can use Mockito's spy and doAnswer functions to override createA on your test fixture with something along the lines of:
Foo foo = new Foo();
Foo spiedFoo = spy(foo); // a spied version when you can copy the behaviour
doAnswer(new Answer() {
#Override
public Object answer(InvocationOnMock inv) throws Throwable {
A a = mock(A.class);
return a;
}
}).when(mySpy).createA(anyInt(), anyInt());
If you have control over the code in question, you can refactor it and make the dependency public, for example by depending on some A-builder. This is probably the best solution, since it makes your class less dependent on A. [Forcing you to decouple your design is one of the main advantages of testing.]