I am trying to write a Junit for a piece of code for asserting the value as null. But the value is changing on the actual call.
Main Class Code
#Activate
public void activate(ComponentContext context)
{
myNotificationSubscriber = NotificationSubscriber.newInstance(myGlobalTableNotificationService,
NotificationType.ENTITIES,
this);
setWantedSubscriptionStatus();
LOG.debug("Activating {} service", getClass().getName());
try
{
applyConfigUpdate(context, IS_ACTIVATION);
}
catch (ServiceNotAvailableException e)
{
String instanceNameWithException = COUNTER_INSTANCE_COBA.concat("-")
.concat(String.valueOf(e.getResponseCode().getResponseCode()))
.concat(e.getClass().getSimpleName());
myCounterregistrator.get()
.incrementCounter(Counter.DATAACCESS_COBA_RESPONSE_UNSUCCESSFUL.getCounterInstance(instanceNameWithException));
LOG.debug("Can not activate Component :{}", e.getMessage());
}
LOG.info("COBA Cache state is {}", myCacheState);
}
private GlobalTableRetriever getGlobalTableRetrieverer() throws ServiceNotAvailableException
{
GlobalTableRetriever tableFetcher = myGlobalTableRetriever.get();
if (tableFetcher == null)
{
throw new ServiceNotAvailableException(RETRIEVER_SERVICE_NOT_AVAILABLE_MSG, ResponseCode.COBA_READ_DATA_TEMPORARY_ERROR);
}
return tableFetcher;
}
I want to write the test for the catch block. So tried to write the test case in below.
#Test
public void testapplyConfigUpdate() throws GlobalTableException
{
exception.expect(ServiceNotAvailableException.class);
globalTableRetriever.set(null);
tableFetcher = globalTableRetriever.get();
assertThat(tableFetcher).isNull();
myTableHandler.activate(myOsgiComponentContext);
verify(myCounterRegistratorService, times(1)).incrementCounter(any(CounterInstance.class));
}
But once its entering to getGlobalTableRetrieverer method, the assertion null value is changing to original.
Why do you even need to assert that?
exception.expect(ServiceNotAvailableException.class);
already implies that tableFetcher is null.
Just try this :
#Test
public void testapplyConfigUpdate() throws GlobalTableException
{
exception.expect(ServiceNotAvailableException.class);
globalTableRetriever.set(null);
tableFetcher = globalTableRetriever.get();
}
Related
class A {
public static int f1() {
return 1;
}
public static int f2() {
return A.f1();
}
}
class ATest {
#Test
void testF2() {
try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class)) {
aStatic.when(A::f1).thenReturn(2);
int ret = A.f2(); // getting 0 here
assertEquals(ret, 2);
} catch(Exception e) {
}
}
}
In the testF2 I want to test static function A::f2().
And it internally calls another static function A::f1().
I did stub A::f1() to return 2 using "MockedStatic" and "when" way.
But it's not working, it's returning 0.
How to solve it?
I think you miss to specify a mock behavior:
class ATest {
#Test
void testF2() {
try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class)) {
aStatic.when(A::f1).thenReturn(2);
aStatic.when(A::f2).thenReturn(A.f1()); // <- added this
int ret = A.f2(); // getting 0 here
Assertions.assertEquals(ret, 2);
} catch (Exception e) {
}
}
}
by telling the mock what to do when A.f2() is invoked, test runs fine.
Update:
Mocks do what you tell them, if you don't tell what to do when a method is invoked they do nothing, that's why you have to mock f2 too.
You want to test A, then mock it is not your friend. I normally use a Mockito.spy() to partially mock my subject under test .You want to mock f1 but test f2, I don't think spy applies here because there is no instance to spy..
I suggest you to rearrange A avoiding static methods if possible or using parameters you can mock.
When you mock a class with static methods, all static methods are mocked. If you only want to mock the behavior of only 1 method, you have to add Mockito.CALLS_REAL_METHODS argument to Mockito.mockStatic() as you can see in the following example.
#Test
void testF2() {
try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class, Mockito.CALLS_REAL_METHODS)) {
aStatic.when(A::f1).thenReturn(2);
int ret = A.f2(); // getting 2 here
Assert.assertEquals(2, ret); // (expected, result)
} catch(Exception e) {
}
}
This way only the f1 method invocation is mocked but f2 invocation calls the real code.
When I want just to add more context to any exception that has happened (including parsing errors and even out of memory) I write code as follows
try {
new JsonSlurper().parseText(response)
} catch (any) {
throw new IllegalStateException("Cannot parse response:\n$response", any)
}
This works fine, but I may end up with OutOfMemoryError being wrapped in IllegalStateException which doesn't sound right, as further there could be dedicated exception handling mechanism just for Error throwables.
Is there any way to just add more context to exception and still preserve its original type or category? I.e. when I get OOME, I want to rethrow Error, when I get some parsing exception, I want to rethrow some unchecked exception etc. And of course I don't want to do it manually for each category, as OOME is pretty unlikely and I don't want to produce special code for corner cases (while still I want to be technically correct).
You can definitely do this in groovy by using its metaprogramming features. In particular, for your case metaclasses provides everything you need. Using them you can dynamically add/attach a contextData object to the exception you want it to carry around:
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
Then to retrieve this contextData in other parts of the code, just inspect the exception object like this:
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
There I am using the argument contextDataHandler as a groovy Closure to handle contextData in a flexible manner.
The following is a full working demo of this:
import java.time.LocalDateTime
class ExceptionEnhancer {
static void main(String[] args) {
def logger = { println "${LocalDateTime.now()} - Context Data = [$it]" }
doSomethingWithContextData logger
}
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
public static void throwsBasicException() throws IOException {
throw new IOException();
}
}
Complete code on GitHub
Hope this helps.
I am working on Teamcenter RAC customization. I have changed an existing code which deals with viewpart and jbuttons on it. The viewpart(SWT) loads a stylesheet rendering panel. the problem is whenever I click on the save button (JButton) this hangs the teamcenter application on post -executing activities.
The code is as follows:
saveCheckOutButton.addActionListener( new ActionListener()
{
#Override
public void actionPerformed( ActionEvent paramAnonymousActionEvent )
{
final AbstractRendering sheetPanel = itemPanel.getStyleSheetPanel();
final AbstractRendering sheetPanel1 = itemRevPanel.getStyleSheetPanel();
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground()
throws Exception
{
if(pPanel==null)
return null;
if( pPanel.isPanelSavable())
{
if(sheetPanel==null|| sheetPanel1==null)
return null;
sheetPanel.saveRendering();
sheetPanel1.saveRendering();
/*if(!sheetPanel.getErrorFlag() && !sheetPanel1.getErrorFlag())
{
sheetPanel.setModifiable( false );
sheetPanel1.setModifiable( false );
}*/
}
return null;
}
#Override
protected void done(){
if(!sheetPanel.getErrorFlag() && !sheetPanel1.getErrorFlag())
{
sheetPanel.setModifiable( false );
sheetPanel1.setModifiable( false );
}
}
};
worker.execute();
}
} );
I have written the code under swingworker as suggested by some of the experts here but to no success. Request for some immediate help.
What do you mean by "it hangs the teamcenter application". Whether it responds too slow or doInBackground() is not properly executed?
Anyway you can try executing your rendering code in SwingUtilities.invokeLater() and use the method get(). If you don't call get() in the done method, you will lose all the exceptions that the computation in the doInBackground() has thrown. So we will get to know about exception if any is there.
SwingUtilities.invokeLater() allows a task to be executed at some later point in time, as the name suggests; but more importantly, the task will be executed on the AWT event dispatch thread. Refer Invoke later API documentation for the detailed info.
About get():
Waits if necessary for the computation to complete, and then retrieves its result.
Note: calling get on the Event Dispatch Thread blocks all events, including repaints, from being processed until this SwingWorker is complete.
saveCheckOutButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent paramAnonymousActionEvent) {
final AbstractRendering sheetPanel = itemPanel.getStyleSheetPanel();
final AbstractRendering sheetPanel1 = itemRevPanel.getStyleSheetPanel();
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
if (pPanel == null)
return null;
if (pPanel.isPanelSavable()) {
if (sheetPanel == null || sheetPanel1 == null)
return null;
saveRendering();
}
return null;
}
#Override
protected void done() {
try {
get();
if (!sheetPanel.getErrorFlag() && !sheetPanel1.getErrorFlag()) {
sheetPanel.setModifiable(false);
sheetPanel1.setModifiable(false);
}
} catch (final InterruptedException ex) {
throw new RuntimeException(ex);
} catch (final ExecutionException ex) {
throw new RuntimeException(ex.getCause());
}
}
};
worker.execute();
}
});
private void saveRendering() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
sheetPanel.saveRendering();
sheetPanel1.saveRendering();
}
});
}
We have a text file where a list of search query and the expected result is given. Such as,
Search Result
a:120 result1
b:220 result2
.....
.....
Now, we need to write a JUnit (heavily used in our daily build) test class, where each of the row will represent one #Test method. So by that, we know, which search case failed (UI).
We already have a solution, where we have one #Test method only, and we have log to check which case passed or failed.
But, we are trying to achieve per case represented as a junit method. Is it really possible, to dynamically create a #Test method to JUnit architecture.
Our, #Test method is same for every search case. That means, we just want to pass a different parameter every time.
I have come up with a JUnit3 solution to my problem. Need help to translate it to Junit4.
public static Test suite()
{
TestSuite suite = new TestSuite();
for ( int i = 1; i <= 5; i++ ) {
final int j = i;
suite.addTest(
new Test1( "testQuery" + i ) {
protected void runTest()
{
try {
testQuery( j );
} catch ( MalformedURLException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch ( SolrServerException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
);
}
return suite;
}
In JUnit 4 there is a concept called "Parameterized Test" that is used for exactly this.
I don't fully understand your test above, but this should give you a hint:
#RunWith(Parameterized.class)
public class ParameterizedTest {
private String query;
private String expectedResult;
public ParameterizedTest(String query, String expectedResult) {
this.query = datum;
this.expectedResult = expectedResult;
}
#Parameters
public static Collection<Object[]> generateData() {
Object[][] data = {
{ "a:120", "result1" },
{ "b:220", "result2" },
};
return Arrays.asList(data);
}
#Test
public void checkQueryResult() {
System.out.println("Checking that the resutl for query " + query + " is " + expectedResult);
// ...
}
}
I have some methods which throws some exception, and I want to use AspectJ around advise to calculate the execution time and if some exception is thrown and to log into error log and continue the flow by re-throwing the exception.
I tried to achieve this by following but eclipse says "Unhandled Exception type".
Code-against whom AspectJ is to used :-
public interface Iface {
public void reload() throws TException;
public TUser getUserFromUserId(int userId, String serverId) throws ResumeNotFoundException, TException;
public TUser getUserFromUsername(String username, String serverId) throws ResumeNotFoundException, TException;
public TResume getPartialActiveProfileFromUserId(int userId, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException;
public TResume getPartialActiveProfileFromUsername(String username, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException, TException;
}
Code AspectJ :-
public aspect AspectServerLog {
public static final Logger ERR_LOG = LoggerFactory.getLogger("error");
Object around() : call (* com.abc.Iface.* (..)) {
Object ret;
Throwable ex = null;
StopWatch watch = new Slf4JStopWatch();
try {
ret = proceed();
} catch (UserNotFoundException e) {
ex = e;
throw e;
} catch (ResumeNotFoundException e) {
ex = e;
throw e;
} catch (Throwable e) {
ex = e;
throw new RuntimeException(e);
} finally {
watch.stop(thisJoinPoint.toShortString());
if (ex != null) {
StringBuilder mesg = new StringBuilder("Exception in ");
mesg.append(thisJoinPoint.toShortString()).append('(');
for (Object o : thisJoinPoint.getArgs()) {
mesg.append(o).append(',');
}
mesg.append(')');
ERR_LOG.error(mesg.toString(), ex);
numEx++;
}
}
return ret;
}
}
Please help why this AspectJ is not working.
you can avoid catching the exceptions and just use a try/finally block without the catch.
And if you really need to log the exception you can use an after throwing advice, like this:
public aspect AspectServerLog {
public static final Logger ERR_LOG = LoggerFactory.getLogger("error");
Object around() : call (* com.abc.Iface.* (..)) {
StopWatch watch = new Slf4JStopWatch();
try {
return proceed();
} finally {
watch.stop(thisJoinPoint.toShortString());
}
}
after() throwing (Exception ex) : call (* com.abc.Iface.* (..)) {
StringBuilder mesg = new StringBuilder("Exception in ");
mesg.append(thisJoinPoint.toShortString()).append('(');
for (Object o : thisJoinPoint.getArgs()) {
mesg.append(o).append(',');
}
mesg.append(')');
ERR_LOG.error(mesg.toString(), ex);
}
}
I'm afraid you cannot write advice to throw exceptions that aren't declared to be thrown at the matched join point. Per: http://www.eclipse.org/aspectj/doc/released/progguide/semantics-advice.html :
"An advice declaration must include a throws clause listing the checked exceptions the body may throw. This list of checked exceptions must be compatible with each target join point of the advice, or an error is signalled by the compiler."
There has been discussion on the aspectj mailing list about improving this situation - see threads like this: http://dev.eclipse.org/mhonarc/lists/aspectj-dev/msg01412.html
but basically what you will need to do is different advice for each variant of exception declaration. For example:
Object around() throws ResumeServiceException, ResumeNotFoundException, TException:
call (* Iface.* (..) throws ResumeServiceException, ResumeNotFoundException, TException) {
that will advise everywhere that has those 3 exceptions.
There is an "ugly" workaround - I found them in Spring4 AbstractTransactionAspect
Object around(...): ... {
try {
return proceed(...);
}
catch (RuntimeException ex) {
throw ex;
}
catch (Error err) {
throw err;
}
catch (Throwable thr) {
Rethrower.rethrow(thr);
throw new IllegalStateException("Should never get here", thr);
}
}
/**
* Ugly but safe workaround: We need to be able to propagate checked exceptions,
* despite AspectJ around advice supporting specifically declared exceptions only.
*/
private static class Rethrower {
public static void rethrow(final Throwable exception) {
class CheckedExceptionRethrower<T extends Throwable> {
#SuppressWarnings("unchecked")
private void rethrow(Throwable exception) throws T {
throw (T) exception;
}
}
new CheckedExceptionRethrower<RuntimeException>().rethrow(exception);
}
}