setting up test data in DB for jBehave test stories - dbunit

I wish to use jBehave in completeness as an integration testing framework and therefore I need some definite way of setting up the Test data in the database before I begin with a particular test story something similar to using DbUnit with jUnit where we define the test data XMLs for each test case. Is there a way to achieve this with or with out DbUnit ?

The spring-security example that is contained in JBehave examples does exactly that. It uses DbUnit to wipe out the database as a #BeforeStory.
If you want specific data, then you might want to create GivenStories or have Givens that load specific data files.
#Given("the gold status users")
public void loadGoldStatusUsers() {
dbunitLoader.load("/goldStatusUsers.xls");
}

Related

Is it a good practice to Mock entity manager in spring boot unit testing

I currently design an API using spring boot. In my service layer, I use Entity Manager for accessing the database. I have provided a method in my service layer below as an example.
public Object getFirstReturnDate(Long vehicle_id, LocalDateTime reservation_date){
String string = "SELECT r.reservation_time from Reservation r left join fetch r.driverAssignment where r.reservation_time > :reservation_time " +
"and r.reserved_status.slug in ('pending','approved') and r.reserved_vehicle.id=:vehicle_id " +
" order by r.reservation_time asc ";
Query query = em.createQuery(string);
query.setParameter("reservation_time",reservation_date);
query.setParameter("vehicle_id",vehicle_id);
List<LocalDateTime> localDateTimes=query.getResultList();
if(localDateTimes.size()==0)
return new DefaultResponseDTO(200, ResponseStatus.OK,"Any Date",null);;
return new DefaultResponseDTO(200, ResponseStatus.OK,"Possible Time",localDateTimes.get(0));
}
in the testing unit, I mocked the entity manager as below,
#Mock
EntityManager em;
And in the test method,
Query query = Mockito.mock(Query.class);
Mockito.when(em.createQuery(Mockito.anyString())).thenReturn(query);
Mockito.when(query.getResultList()).thenReturn(new LinkedList());
My question is, if I mock entity Manger as I mentioned above then the query in the method didn't get checked. Is it a bad coding practice?
Is there any other way to check queries without calling the database?
Any testing approach should be part of a comprehensive testing strategy. I.e. you should know which types of bugs you expect your unit tests to find, which types of bugs you expect integration and E2E tests to find, etc.
Mocking an EntityManager has pros:
It is easier to test your business logic in isolation
You can set up hypothetical scenarios with ease
Your tests will be much faster as you don't establish a connection to the database
But also cons:
You do not test your database connection and configuration
So the question is, where are you testing for database integration issues if they are not check in this test? Once you know the answer to that question you will know the answer to the one you have asked above.
I would recommend reviewing the "Testing Strategies in a Microservice Architecture" for a more in-depth view of how to approach your testing.

junit add more test classes dynamically per user request (rerun tests) for integration testing

I am looking for a way to start the spring context, intialize all caches and after that ask the user on the command line (cmd) what tests he want to execute.
after the tests are run the user can choose to rerun the tests or run different tests until he decide to stop the programm.
this should be based on junit as it enables us to use the same tests within different execution environments (eg. jenkins build, ...)
is there a framework that support something like this or any other adwise how to implement this?
while(true) {
userInput = parseUserInputFromConsole();
if (userWantToExit(userInput)) {
break;
} else {
JunitResult = runJunitTetsBasedOnUserInput(userInput);
generateTestRunReport(JunitResult);
}
}
additional, one test exists of more then one step, but the steps should be reusable among tests. any idea how to implement this?
You can do this by using Spring #ActiveProfiles annotation, you need to basically set which tests are applicable for which run like below:
#ContextConfiguration
#ActiveProfiles({"dev", "integration"})
public class DeveloperIntegrationTests {
// class body...
}
You can look at here

Spring test : strange behavior of context config caching between test classes ?

I am writing tests for a Spring Integration project, and I am running into something strange : I've read about how Spring caches the context between tests and how we can force to clean the cache with #DirtiesContext annotation. However, I'm not able to explain the behavior I observe, and it makes me think it's maybe a bug...
I have 2 different tests :
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:myInterface-core.xml",
"classpath:myInterface-datasource-test.xml"})
public class PropertyConfigurerTest {
#Test
public void shouldResolvePropertyForOutPutFile(){
}
}
(it does nothing, simply loads the context, intentionnaly)
And another one, more complex with actual tests in it (skipping them in below snippet) :
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {
"classpath:myInterface-core.xml",
"classpath:myInterface-rmi.xml",
"classpath:myInterface-datasource-test.xml"})
public class MontranMessagesFlowTest {
...
}
As you can see, these 2 tests don't load exactly the same config : second test loads one extra config file that is not required for first one.
When I run these 2 tests one after the other, second test is failing : in a nutshell, the goal of the test is to insert 2 rows in inMemory DB, start my Spring Integration flow and assert with a listener (inside a jms:listener-container) that I've received 2 JMS messages on the outbound side. I see in debug mode that actually the 2 messages don't go to same listener so I get one message instead of the 2 I expect. Somehow, the fact that I'm loading some elements of the context in first test (even if I don't do anything with them) has an impact on the second test.
I have found 2 different workarounds :
adding #DirtiesContext(classMode=ClassMode.AFTER_CLASS) on my first test.
modify the list of Spring files that I load in my first test, so that it matches exactly the one defined in the second test.
But still, I don't understand the rationale, and it looks like a bug to me.
I am using Spring Test 4.1.4.RELEASE. I've put the minimum code necessary in a separate project to be able to reproduce. I can share it if required.
Does anybody have an explanation for this ? Bug or not ?
Thanks
Vincent
#M. Deinum is correct in his comment.
For what it's worth, in Spring Integration framework tests themselves, we have started adding #DirtiesContext to all tests, to ensure any active components (such as inbound message-driven adapters) are always stopped after the tests complete.
This also has a performance/memory usage improvement for large test suites.

Questions regarding best use of testng and mockito

I am very new for testng(unit testing) and mockito. I have read some articles and went through some code snippets on Internet. But still I have some doubts regarding unit testing with testng & mockito in spring framework.
For unit testing a service layer we mock a DAO. What if I want to test a function wich fetch some data from database and do some operations. How does mock DAO works here. From where mocked DAO will get some data for testing such a function.
If am doing a validation like Data not present in database and I want to test wheather it throws correct exception for that. So it needs some values in database and mocked DAO will check if data present in that predefined database(in-memory). How to provide such a data.
Does dataprovider helps to provide a data to used by DAO. If yes, How it can be done?
Please correct me if my understanding regarding unit testing is correct. Please let me know where I am getting it wrong if I miss understood a concept.
Thank you.
1) Besides UnitTests, you also need Integration and / or Acceptance-Tests.
The Unit-Tests will test that your SUT - Single Unit of Test, in this case a specific service class works as intended, without integrating it with other classes or systems (DB). However, additionally I would write an Integration Test for this Service that retrieves / manipulates test data from the database. This test should ideally not make any assumptions about the data in the database, so inserting the data you will be looking for, before executing the test, is recommended, e.g. using a #Before annotation and actually committing this test data into the test database. However, I further recommend you to do a proper cleanup of the database, in the #After test method. Auto rolling back the data could be done, but is not as optimal, especially if you have a persistence framework like Hibernate or JPA in between. Only when you work on committed data that is really in the physical (not virtual!) dabase, you can be 100% sure your test succeeded.
If I correctly understood your intend, this actually sounds like a perfect reason for mocking your DB / persistence object - make it throw the expected exception / return an empty result, that test that your code behaves as expected on this condition.
A TestNG Dataprovider actually does the opposite of what you are looking for - it is a way to provide an array of data to your test method:
org.testng.annotations.DataProvider
Annotation Type DataProvider
Mark a method as supplying data for a test method. The data provider name defaults to method name. The annotated method must return an Object[][] where each Object[] can be assigned the parameter list of the test method. The #Test method that wants to receive data from this DataProvider needs to use a dataProvider name equals to the name of this annotation.

Commit/Flush transactions during unit test?

I am using Spring and JUnit to write some integration tests for my DAO. I set up my test data in the beginning of the test method, and then test my DAO methods later in the same test method. The problem is that if I don't flush/commit the transaction, the EntityManager returns the same instance of the entities that I have just created in my data setup - rendering my test useless as they will always pass.
E.g.
#Test
#Transactional()
public void loadTreeBasicCase() {
// creates and saved node to DB
Node n = createNode();
// test DAO
Node result = dao.lookup(n.getId());
// verify
assertThat(n, equalTo(result));
}
One way is to expose commit() and/or flush() methods in my DAO. But I would prefer not to do that because in production code, this almost never needs to happen (let EntityManager do it's thing). Is there a way to configure this via annotations or in Spring config? I am using Spring, JPA2 with Hibernate.
You can set the defaultRollback attribute on #Transactional to reset things between tests. This doesn't sound like what you are asking for, just throwing it out there first.
Within the test, the entity manager is behaving correctly. You want to inject different behavior for testing to "disconnect" the setup from the rest of the test. One thing I did in some tests was to call flush on the entity manager directly from the test. I only had to do it a few times, but it was valuable in those cases. I did it in the test (not the DAO) so as to not provide a method on the DAO that I don't want people calling.

Resources