Junit - Running 1 test works, multiple fail on Assertion - java

I am having an issue where if I try running multiple tests of a similar type as what is shown below, the test fails on the assertTrue call. Running a test case separately or in the debugger gives the expected results though. I tried researching this obviously, and it said that maybe I wasn't cleaning up correctly, so I added the #After annotation. This Dao test is using an in-memory hsql database. I'm still not quite sure what I am doing wrong here. Any suggestions?
Thanks!
public class ConfigDaoTest
{
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigDaoTest.class);
private static final String DOC_ID="12345678";
private static final String STATUS_INDICATOR="S";
private static final String FILE_NAME="Testing.txt";
private DaoTestResources resources;
#Before
public void setUp()
{
resources = new DaoTestResources();
System.setProperty("IS_JUNIT_TEST", "TRUE");
}
#After
public void cleanUp()
{
resources = null;
}
#Test
public void testUpdateNotice() {
boolean retVal = false;
try {
retVal = new ConfigDao(ConfigurationManager.getInstance("test/resources/junit.test.properties")).updateNoticeByFileName(FILE_NAME,DOC_ID,STATUS_INDICATOR);
}catch(SQLException e) {
LOGGER.debug("ErrorText:" + e.getMessage());
assertNotNull(true);
}
assertTrue(retVal);
System.out.println("Return value: " + retVal);
assertNotNull(retVal);
}
// More tests like the above.
}

I'm not quite sure why this worked for me (if someone does know, I would love to know the technical details), but I removed cleanUp() and changed #Before to #BeforeClass, and now each of my test cases is running as expected when built with ant both from CL and Eclipse. My best guess is that there was some issue being caused by initializing the hsqldb before each test - that's what the resource class does.

Related

Unable to mock System class static method using PowerMockito

Even though I have read the manual and gone through multiple answers for Powermock, could not mock a static method for my use case.
Class:
#Component
public class SCUtil{
public void createSC(){
try {
String host = InetAddress.getLocalHost().getHostAddress();
// ...
// ...
// ...
} catch (UnknownHostException e) {
log.error("Exception in creasting SC");
throw new ServiceException(e);
}
}
}
Test class:
#RunWith(PowerMockRunner.class)
#PrepareForTest( InetAddress.class )
public class SCUtilTest {
#InjectMocks
private SCUtil scUtil;
private Event event;
#Before
public void beforeEveryTest () {
event = new InterventionEvent();
}
#Test(expected = ServiceException.class)
public void testCreateSC_Exception () {
PowerMockito.mockStatic(InetAddress.class);
PowerMockito.when(InetAddress.getLocalHost()).thenThrow(new UnknownHostException("test"));
scUtil.createSC(event);
}
}
Here, the test is failing as no exception is being thrown:
java.lang.AssertionError: Expected exception:
com.example.v1.test.selftest.errorhandling.ServiceException
I have wrecked more than a couple of hours in this and still have not gotten it to work. What am I doing wrong?
Thank you for all the help in advance :)
java.net.InetAddress is a system class. The caller of the system class should be defined in #PrepareForTest({ClassThatCallsTheSystemClass.class}).
See documentation.
The way to go about mocking system classes are a bit different than
usual though. Normally you would prepare the class that contains the
static methods (let's call it X) you like to mock but because it's
impossible for PowerMock to prepare a system class for testing so
another approach has to be taken. So instead of preparing X you
prepare the class that calls the static methods in X!
Please note #InjectMocks annotation does not inject static mocks, it can be removed.
Example of working test:
#RunWith(PowerMockRunner.class)
#PrepareForTest(SCUtil.class)
public class SCUtilTest {
private SCUtil scUtil = new SCUtil();
#Test(expected = ServiceException.class)
public void testCreateSC_Exception () throws UnknownHostException {
PowerMockito.mockStatic(InetAddress.class);
PowerMockito.when(InetAddress.getLocalHost()).thenThrow(new UnknownHostException("test"));
scUtil.createSC();
}
}

set up one time code for test using #beforeeach

So I have to create one Integration testing and I require to setup a code only once and not before each tests. I checked many articles and it seems JUnit don't provide anything which will help us to code like that. I came across one efficient way to solve this by using below structure but it didn't worked for me.
private static boolean setUpIsDone = false;
#BeforeEach
public void createGame() {
if (setUpIsDone) {
return;
}
//setupcode
setUpIsDone = true;
}
While this should work, it didn't worked for me.
My Integration test code -
public class GameServiceIntegrationTest {
#Autowired
private GameService gameService;
#Autowired
UserService userService;
private Game testGame;
private long gameId=-1;
private static boolean setUpIsDone = false;
#BeforeEach
public void createGame() {
/*
if (setUpIsDone) {
return;
}*/
User testUser = new User();
testUser.setUsername("gamer");
testUser.setPassword("123");
testUser = userService.createUser(testUser);
List<Long> playerIdList = new ArrayList<>();
playerIdList.add(testUser.getId());
gameId = gameService.createGame(playerIdList);
testGame = gameService.getExistingGame(gameId);
// setUpIsDone = true;
}
#Test
public void chooseWord(){
System.out.println("game id here1 ->"+gameId);
int chooseIndex = 1;
gameService.chooseWord(gameId,chooseIndex);
testGame = gameService.getExistingGame(gameId);
assertEquals(testGame.getWordIndex(),0);
}
I want to use gameId variable in every other test that I continue further. If I am using the current version of code, I am getting the exception that object is already created and is failing. So it seems that setup is being executed before every test and the last test value persists.
And if I uncomment the code for setupIsDone process, I am getting gameId as -1 in other test classes. So it seems that the value is not persisting after the first test.
If there is any way to save the data in setup phase for testing overcoming above problem?
How about declaring testGame as static and then checking to see if testGame == null at the top of createGame()?

Powermock can't mock static class

I have a class with code similar to :
public class class1{
private static final ConfigurationService config = Util.getInstance(ConfigurationService.class);
private SendQueueMessages sender;
public void start() throws LifecycleException{
LOGGER.info("Starting");
final ActiveMq activemq = config.getConfiguration().getActiveMq();
sender = new SendQueueMessages(activemq.getQueueName());
}
}
Elsewhere in the program Guice is being used to bind the configuration service and Util like so:
Util.register(new ThingICantChange(){
#Override
protected void configure (){
super.configure();
bind(ConfigurationService.class).to(ConfigurationServiceImpl.class).asEagerSingleton();
}
});
Is this possible to unit test? I was initially trying to use JUnit 5 and mockito, but it became apparent that I needed to mock static classes/methods (IoCUtils) and switched to JUnit4 for PowerMock.
I have tried:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Util.class)
public class Class1Test{
#Test
public void canStart(){
mockStatic(Util.class);
when(Util.getInstance(ConfigurationService.class)).thenReturn(new ConfigurationService);
Class1 class = new Class1();
class.start();
//etc.
}
}
However this just gives me an error about Util not prepared for test. Changing mockStatic() to PowerMockito.spy() did get me to the when, but then throws a null pointer error.
I found a solution, though I have mixed feelings about it.
Using the Util.register (the 2nd code block) I registered a configuration service implementation that created the mock objects. This worked and let me test the start() method, but feels kind of against the idea of a unit test.
public class ConfigServiceTest implements ConfigurationService{
#Override
public Configuration getConfiguration() {
Configuration conf = mock(Configuration.class);
ActiveMq amq = mock(ActiveMq.class);
when(amq.getQueueName()).thenReturn("test");
when(amq.getBrokerUrl()).thenReturn("http://127.0.0.1:61616?soTimeout=1000");
when(conf.getActiveMq()).thenReturn(amq);
return conf;
}
//other methods just allowed to return null
}
Then in the test:
Util.register(new thingICantChange(){
#Override
protected void configure (){
super.configure();
bind(ConfigurationService.class).to(ConfigServiceTest.class).asEagerSingleton();
}
});
class1 service = new class1();
service.start();
Assert.assertEquals(true, true);
start is void and not int a new thread so Assert.assertEquals(true,true) is the best anyone around me knew to check that start ran. Mockito/PowerMock times(1) would require a mock of class1 which seems rather counter to a unit test to see IF it can run.

In Junit, how to prevent from printing expected exception which is thrown intentionally and caught already in log?

I guess this is a junit and Logback problem. In my project, Logging is done through slf4j. The logging implementation is Logback.
So I have a class:
#Component
#Slf4j
public class A {
private final ObjectMapper objectMapper = new ObjectMapper();
private static final String DEFAULT_REPLY = "just continue...";
public String doSomething(Object value) {
try {
return objectMapper.methodAbc(value);
} catch (JPException e) {
log.error("Exception while processing value", e);
return DEFAULT_REPLY;
}
}
}
and its test class
#RunWith(MockitoJUnitRunner.class)
public class ATest {
#Before
public void init() {
processor = new A();
}
#Test
public void test() throws Exception {
ObjectMapper mockMapper = mock(ObjectMapper.class);
JP mockJp = mock(JP.class);
Exception thrownException = new JPException(mockJp, null);
when(mockMapper.methodAbc(any())).thenThrow(thrownException);
String result = processor.doSomething("abc");
assertTrue(result.equals("just continue..."));
}
}
I don't have any problem with the test itself. Just as you can see, in the test, the JPException will be printing out on the log, because it's intentionally thrown.
When I debug through logs, there're too many this kind of expected exceptions, I'm just wondering is there a way to remove them from logs? And of course still print other exceptions which is not expected.
Logback has the functionality to support filters and evaluations based on certain logic.
This link is probably what you could be looking for :
https://logback.qos.ch/manual/layouts.html#Evaluators
You can configure your logback to do or not do certain action if it is an instance of any exceptio - in your case JPException
Try this:
Create a mock for the log.
Inject the mock into the class being tested.
Assert that the error method on the mocked log object was called.

Spring Parameterized/Theories JUnit Tests

I'm looking to combine the flexibility of Spring Profiles and Configurations with the parallel running of JUnit tests which utilize either the Parameterized or Theories annotation. Is there any way to incorporate all of these features to get my unit tests running?
The problem I keep running into is the parameters need access to an injected bean, which isn't possible since the function annotated with #Parameters or #DataPoints is supposed to be static. I'd really hate to have to wire that into each class or even a static function somewhere because I'd like to quickly be able to switch profiles without having to change Java code. Is this possible?
Found the ticket for this request. It seems the attached file has some issues though. Looks like it's been a feature request for quite some time now.
I've been looking for a solution of this problem too. And there is one ! But as it comes from somebody's blog, I can't take the credit for it however. :-)
Unfortunately I can't find the original blog any more...
#RunWith(Parameterized.class)
#ContextConfiguration("/beans.xml")
public class MyTest {
private final File file;
public MyTest(final File file) {
this.file = file;
}
#Autowired
private PlatformTransactionManager transactionManager;
private TestContextManager testContextManager;
#Parameterized.Parameters
public static Collection<File[]> getFilesToTest() throws Exception {
return getValidFiles();
}
#Before
public void setUpSpringContext() throws Exception {
testContextManager = new TestContextManager(getClass());
testContextManager.prepareTestInstance(this); // does the autowiring !
}
#Test
public void testInTransactionContext() throws Exception {
new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
public Object doInTransaction(final TransactionStatus status) {
status.setRollbackOnly();
try {
... run the test ...
} catch (Exception e) {
throw new RuntimeException(e);
}
return null;
}
});
}
}

Categories

Resources