mockito simulate test exception thrown by service - junit

I am trying to test exception thrown from service when I use the instance of it.
Like I am trying to use Imock in Trans.class and use IMock method.
Below is the code
public class MockImpl implements IMock{
public String external(String str) throws Exception {
if(str.equals("throw")){
throw new Exception("Thrown exception.");
}
return str;
}
}
public class Trans {
private IMock mc;
public static int failed;
public String performTrans(String str) throws Exception {
return call(str);
}
private String call(String str) throws Exception {
mc = new MockImpl();
try {
return mc.external(str);
}
catch(Exception e){
failed++;
throw e;
}
}
}
In test class I am trying to do this
public class TestMock {
#Test
public void testMock() throws Exception {
Trans trans = mock(Trans.class);
IMock iMock = mock(IMock.class);
doThrow(new Exception()).when(iMock).external(any(String.class));
for(int i =0;i<10 ;i++){
trans.performTrans("any");
}
System.out.println(Trans.failed);
assertEquals(9, Trans.failed);
}
}
As I am new to this, I am not sure if my understanding is correct, what I am trying to achieve is
When I do # Trans.performTrans(String);
Then doThrow(new Exception()).when(iMock).external(any(String.class)); should happen. How can I tell Mockito or any test framework that The exception should be thrown should be simulated from the Imock service method, even if it is indirectly called.
UPDATE
After trying to test this way
#RunWith(MockitoJUnitRunner.class)
public class TestMock {
#Test
public void testMock() throws Exception {
Trans trans = new Trans();
IMock iMock = mock(IMock.class);
trans.setInter(iMock);
//doThrow(new Exception()).when(iMock).external(any(String.class));
trans.performTrans("abc");
verify(iMock).external(new String("a"));
System.out.println(Trans.failed);
assertEquals(9, Trans.failed);
}
}
I get this error.
Wanted but not invoked: iMock.external("a");
-> at com.app.TestMock.testMock(TestMock.java:32) Actually, there were zero interactions with this mock.
what could be wrong?

Related

How to test keyedbroadcastprocessfunction in flink?

I am new to flink i am trying write junit test cases to test KeyedBroadCastProcessFunction. Below is my code ,i am currently calling the getDataStreamOutput method in TestUtils class and passing inputdata and patternrules to method once the input data is evaluated against list of pattern rules and if input data satisfy the condition i will get the signal and calling sink function and returning output data as string in getDataStreamOutput method
#Test
public void testCompareInputAndOutputDataForInputSignal() throws Exception {
Assertions.assertEquals(sampleInputSignal,
TestUtils.getDataStreamOutput(
inputSignal,
patternRules));
}
public static String getDataStreamOutput(JSONObject input, Map<String, String> patternRules) throws Exception {
env.setParallelism(1);
DataStream<JSONObject> inputSignal = env.fromElements(input);
DataStream<Map<String, String>> rawPatternStream =
env.fromElements(patternRules);
//Generate a key,value pair of set of patterns where key is pattern name and value is pattern condition
DataStream<Tuple2<String, Map<String, String>>> patternRuleStream =
rawPatternStream.flatMap(new FlatMapFunction<Map<String, String>,
Tuple2<String, Map<String, String>>>() {
#Override
public void flatMap(Map<String, String> patternRules,
Collector<Tuple2<String, Map<String, String>>> out) throws Exception {
for (Map.Entry<String, String> stringEntry : patternRules.entrySet()) {
JSONObject jsonObject = new JSONObject(stringEntry.getValue());
Map<String, String> map = new HashMap<>();
for (String key : jsonObject.keySet()) {
String value = jsonObject.get(key).toString();
map.put(key, value);
}
out.collect(new Tuple2<>(stringEntry.getKey(), map));
}
}
});
BroadcastStream<Tuple2<String, Map<String, String>>> patternRuleBroadcast =
patternStream.broadcast(patternRuleDescriptor);
DataStream<Tuple2<String, JSONObject>> validSignal = inputSignal.map(new MapFunction<JSONObject,
Tuple2<String, JSONObject>>() {
#Override
public Tuple2<String, JSONObject> map(JSONObject inputSignal) throws Exception {
String source =
inputSignal.getSource();
return new Tuple2<>(source, inputSignal);
}
}).keyBy(0).connect(patternRuleBroadcast).process(new MyKeyedBroadCastProcessFunction());
validSignal.map(new MapFunction<Tuple2<String, JSONObject>,
JSONObject>() {
#Override
public JSONObject map(Tuple2<String, JSONObject> inputSignal) throws Exception {
return inputSignal.f1;
}
}).addSink(new getDataStreamOutput());
env.execute("TestFlink");
}
return (getDataStreamOutput.dataStreamOutput);
}
#SuppressWarnings("serial")
public static final class getDataStreamOutput implements SinkFunction<JSONObject> {
public static String dataStreamOutput;
public void invoke(JSONObject inputSignal) throws Exception {
dataStreamOutput = inputSignal.toString();
}
}
I need to test different inputs with same broadcast rules but each time i am calling this function its again and again doing process from beginning take input signal broadcast data, is there a way i can broadcast once and keeping on sending the input to the method i explored i can use CoFlatMapFunction something like below to combine datastream and keep on sending the input rules while method is running but for this one of the datastream has to keep on getting data from kafka topic again it will overburden on method to load kafka utils and server
DataStream<JSONObject> inputSignalFromKafka = env.addSource(inputSignalKafka);
DataStream<org.json.JSONObject> inputSignalFromMethod = env.fromElements(inputSignal));
DataStream<JSONObject> inputSignal = inputSignalFromMethod.connect(inputSignalFromKafka)
.flatMap(new SignalCoFlatMapper());
public static class SignalCoFlatMapper
implements CoFlatMapFunction<JSONObject, JSONObject, JSONObject> {
#Override
public void flatMap1(JSONObject inputValue, Collector<JSONObject> out) throws Exception {
out.collect(inputValue);
}
#Override
public void flatMap2(JSONObject kafkaValue, Collector<JSONObject> out) throws Exception {
out.collect(kafkaValue);
}
}
I found a link in stackoverflow How to unit test BroadcastProcessFunction in flink when processElement depends on broadcasted data but this is confused me a lot
Any way i can only broadcast only once in Before method in test cases and keeping sending different kind of data to my broadcast function
You can use KeyedTwoInputStreamOperatorTestHarness in order to achieve this for example let's assume you have the following KeyedBroadcastProcessFunction where you define some business logic for both DataStream channels
public class SimpleKeyedBroadcastProcessFunction extends KeyedBroadcastProcessFunction<String, String, String, String> {
#Override
public void processElement(String inputEntry,
ReadOnlyContext readOnlyContext, Collector<String> collector) throws Exception {
//business logic for how you want to process your data stream records
}
#Override
public void processBroadcastElement(String broadcastInput, Context
context, Collector<String> collector) throws Exception {
//process input from your broadcast channel
}
Let's now assume your process function is stateful and is making modifications to the Flink internal state, you would have to create a TestHarness inside your test class to ensure you are able to keep track of the state during testing.
I would then create some unit tests using the following approach:
public class SimpleKeyedBroadcastProcessFunctionTest {
private SimpleKeyedBroadcastProcessFunction processFunction;
private KeyedTwoInputStreamOperatorTestHarness<String, String, String, String> testHarness;
#Before
public void setup() throws Exception {
processFunction = new SimpleKeyedBroadcastProcessFunction();
testHarness = new KeyedTwoInputStreamOperatorTestHarness<>(
new CoBroadcastWithKeyedOperator<>(processFunction, ImmutableList.of(BROADCAST_MAP_STATE_DESCRIPTOR)),
(KeySelector<String, String>) string -> string ,
(KeySelector<String, String>) string -> string,
TypeInformation.of(String.class));
testHarness.setup();
testHarness.open();
}
#After
public void cleanup() throws Exception {
testHarness.close();
}
#Test
public void testProcessRegularInput() throws Exception {
//processElement1 send elements into your regular stream, second param will be the event time of the record
testHarness.processElement1(new StreamRecord<>("Hello", 0));
//Access records collected during processElement
List<StreamRecord<? extends String>> records = testHarness.extractOutputStreamRecords();
assertEquals("Hello", records.get(0).getValue())
}
#Test
public void testProcessBroadcastInput() throws Exception {
//processElement2 send elements into your broadcast stream, second param will be the event time of the record
testHarness.processElement2(new StreamRecord<>("Hello from Broadcast", 0));
//Access records collected during processElement
List<StreamRecord<? extends String>> records = testHarness.extractOutputStreamRecords();
assertEquals("Hello from Broadcast", records.get(0).getValue())
}
}

How to mock a void private method to throw Abstract Exception with Powermock?

While writing unit test case for method someMethod1, I have a use case where I'm trying to ensure that an abstract exception (AnalysisException) is thrown when method (someMethod2) is called. Class under test is JdbcTemplateSampleImpl .
public class JdbcTemplateSampleImpl {
public void someMethod1() {
someMethod2();
}
private void someMethod2() throws AnalysisException {
// some code here
}
}
I am using PowerMockito to do like this
#Test(expected = com.test.AnalysisException.class)
public void abstractClassExceptionCheck2Test1() throws Throwable {
JdbcTemplateSampleImpl jdbcTemplateSampleImpl1 =
PowerMockito.spy(jdbcTemplateSampleImpl0);
PowerMockito.doThrow(mock(AnalysisException.class)).
when(jdbcTemplateSampleImpl1,"classCheck2");
jdbcTemplateSampleImpl1.abstractClassExceptionCheck2();
}
But while executing test case , i'm getting an error like this
java.lang.Exception: Unexpected exception, expected "com.test.AnalysisException" but was "java.lang.NullPointerException"
Mock the exception outside of the doThrow method call.
AnalysisException e = mock(AnalysisException.class);
PowerMockito.doThrow(e).
when(jdbcTemplateSampleImpl1,"classCheck2");

Test with ExpectedException fails when using PoweMock with PowerMockRule

I am trying to work with PowerMock, over Mockito; as I loved the API's for whennew() and verifyprivate() but i have some problem when trying to run testsuites with Categories TestRunner in Junit.
For using default JUnit test runners, I created a TestCase and added PowerMockRule as instance field with #Rule annotation. While execution of tests worked like this, ExpectedException TestRule is not working when used in conjunction
Example Code
#PowerMockIgnore ("*")
#PrepareForTest (CustomizedSSHConnection.class)
public class TestExpectedExceptionRule {
private Connection connection;
private ConnectionInfo connectionInfo;
#Rule
public PowerMockRule rule = new PowerMockRule ();
#Rule
public ExpectedException exception = ExpectedException.none ();
#Test
public void testExcepitonWithPowerMockRule() {
exception.expect (NullPointerException.class);
exception.expectMessage ("Image is null");
throw new NullPointerException ("Image is null");
}
}
Instead of using #Rule PowerMockRule if I use #RunWith(PowerMockRunner.class) this testcase will pass.
One other observation is if I annotate PowerMockRule with #ClassRule this succeeds but some of the mocking methods throwing exceptions.
PowerMock creates a deep clone of the TestExpectedExceptionRule object. Because of this it is running the test with a new ExpectedException rule, but you're calling exception.expect (NullPointerException.class) on the original rule. Hence the test fails, because the clone of the ExpectedException rule doesn't expect an exception.
Nevertheless there are at least two solutions for your problem.
RuleChain
Order the rules with JUnit's RuleChain. This needs some additional ugly code, but it works.
private ExpectedException exception = ExpectedException.none ();
private PowerMockRule powerMockRule = new PowerMockRule();
#Rule
public TestRule ruleChain = RuleChain.outerRule(new TestRule() {
#Override
public Statement apply(Statement base, Description description) {
return powerMockRule.apply(base, null, description);
}
}).around(exception);
Fishbowl
If you are using Java 8 then you can replace the ExpectedException rule with the Fishbowl library.
#Test
public void testExcepitonWithPowerMockRule() {
Throwable exception = exceptionThrownBy(
() -> throw new NullPointerException ("Image is null"));
assertEquals(NullPointerException.class, exception.getClass());
assertEquals("Image is null", exception.getMessage());
}
Without Java 8, you have to use an anonymous class.
#Test
public void fooTest() {
Throwable exception = exceptionThrownBy(new Statement() {
public void evaluate() throws Throwable {
throw new NullPointerException ("Image is null");
}
});
assertEquals(NullPointerException.class, exception.getClass());
assertEquals("Image is null", exception.getMessage());
}
I was able to fix this using the expected attribute in the #Test annotation. But the problem with this approach is that am unable to assert the exception message. Which is fine for me for now.
#PowerMockIgnore ("*")
#PrepareForTest (CustomizedSSHConnection.class)
public class TestExpectedExceptionRule {
private Connection connection;
private ConnectionInfo connectionInfo;
#Rule
public PowerMockRule rule = new PowerMockRule ();
#Rule
public ExpectedException exception = ExpectedException.none ();
#Test(expected = NullPointerException.class)
public void testExcepitonWithPowerMockRule() {
throw new NullPointerException ("Image is null");
}
}
I solved this problem by creating a PowerMockTestUtil class that uses a FunctionalInterface.
Utility class:
/**
* Utility class to provide some testing functionality that doesn't play well with Powermock out
* of the box. For example, #Rule doesn't work well with Powermock.
*/
public class PowerMockTestUtil {
public static void expectException(RunnableWithExceptions function, Class expectedClass, String expectedMessage) {
try {
function.run();
fail("Test did not generate expected exception of type " + expectedClass.getSimpleName());
} catch (Exception e) {
assertTrue(e.getClass().isAssignableFrom(expectedClass));
assertEquals(expectedMessage, e.getMessage());
}
}
#FunctionalInterface
public interface RunnableWithExceptions<E extends Exception> {
void run() throws E;
}
}
Sample test:
#Test
public void testValidateMissingQuantityForNewItem() throws Exception {
...
expectException(() -> catalogEntryAssociationImporter.validate(line),
ImportValidationException.class,
"Quantity is required for new associations");
}

ClientResponse Failure in mockito test cases

Iam working on mockito testcases positive test methods are getting executed but comming to Exception Test methods its failing with the Exception
java.lang.Exception: Unexpected exception, expected<com.apple.ist.retail.xcard.common.exception.InvalidArgumentException> but was<org.jboss.resteasy.client.ClientResponseFailure>
at
Below is the test method which is failing and its parent class containing client object
package com.apple.ist.retail.xcard.ws.exception;
public class TestActivatePrepaidCard extends CertificateResourceTestCase {
public TestActivatePrepaidCard(String aMediaType) {
super(aMediaType);
}
#Before
public void setUp() {
super.setUp();
}
#Test(expected = InvalidArgumentException.class)
public void testActivatePrepaidCard_InvalidArgumentException()
throws DuplicateCertificateIDException, InvalidArgumentException,
DupTxnRefException, AmountException, SystemException,
XCardException {
when(
server.activatePrepaidCard(any(DiagnosticContext.class),
any(String.class), any(Number.class),
any(Amount.class), any(String.class), any(int.class),
any(HashMap.class), any(String.class),
any(SalesOrg.class), any(TxnRef.class))).thenThrow(
new InvalidArgumentException("Invalid Argument ",
INVALID_ARGUMENT));
client.activatePrepaidCard(certificateRequest);
}
Its failing near client.activatePrepaidCard(certificateRequest); with ClientResponseFailure Exception
Parent test case is
package com.apple.ist.retail.xcard.ws.exception;
#RunWith(value = Parameterized.class)
public abstract class CertificateResourceTestCase extends Assert {
protected CertificateResource client;
protected XCardServiceServer server;
protected CertificateResource resource;
protected CertificateRequest certificateRequest;
// protected Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
private String mediaType;
public CertificateResourceTestCase(String aMediaType) {
this.mediaType = aMediaType;
server = mock(XCardServiceServer.class);
CertificateResourceImpl xcardServiceRs = new CertificateResourceImpl();
xcardServiceRs.setService(server);
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getRegistry().addSingletonResource(xcardServiceRs);
dispatcher.getProviderFactory().addExceptionMapper(
XCardExceptionMapper.class);
dispatcher.getProviderFactory().addExceptionMapper(
BusinessExceptionMapper.class);
dispatcher.getProviderFactory().addExceptionMapper(
RuntimeExceptionMapper.class);
dispatcher.getProviderFactory().addExceptionMapper(
BusinessExceptionMapper.class);
dispatcher.getProviderFactory().addExceptionMapper(
RuntimeExceptionMapper.class);
dispatcher.getProviderFactory()
.getServerMessageBodyWriterInterceptorRegistry()
.register(new XCardTxnWriterInterceptor());
dispatcher.getProviderFactory().getContextDataMap()
.put(HttpServletRequest.class, new MockHttpServletRequest());
client = ProxyFactory.create(CertificateResource.class, "/", new InMemoryClientExecutor(dispatcher));
diagnosticContext.setReportingRecommended(false);
}
#After
public void tearDown() throws Exception {
Mockito.reset(server);
}
Please let me know whats wrong in my code,I am pasting complete code so that I will not miss any detail
Your code is throwing an ClientResponseFailure. Debug your test and find out why. Use an exception breakpoint.

JMock triggers AssertionError: invokation expected once, never invoked - but it has been invoked

I'm pretty new to programming with java but I've tried to directly start with unit-testing and therefore also used JMock. I have already implemented some test-cases (with JMock) that work, but this one I just can't get to run.
What I did:
I wrote a test-class which creates a mock object and then I'm expectation one (using oneOf) invocation. After running the unit test it says it fails (but the logs say otherwise, as i print out the data I returned at the invocation using will(returnValue(x)).
The next funny/weird thing is - if I change the oneOf to "never" the unit test succeeds, but it throws an Exception:
Exception in thread "Thread-2" java.lang.AssertionError: unexpected invocation: blockingQueue.take()
expectations:
expected never, never invoked: blockingQueue.take(); returns
what happened before this: nothing!
Here the code:
#RunWith(JMock.class)
public class ExecuteGameRunnableTest {
private Mockery context = new JUnit4Mockery();
private Thread testObject;
private BlockingQueue<Game> queueMock;
private Executor executorMock;
#SuppressWarnings("unchecked")
#Before
public void setUp() {
queueMock = context.mock(BlockingQueue.class);
executorMock = context.mock(Executor.class);
testObject = new Thread(new ExecuteGameRunnable(queueMock, executorMock, true));
}
#After
public void tearDown() {
queueMock = null;
executorMock = null;
testObject = null;
}
#Test
public void testQueueTake() throws InterruptedException {
final Game game = new Game();
game.setId(1);
game.setProcessing(false);
context.checking(new Expectations() {{
never(queueMock).take(); will(returnValue(game));
}});
testObject.start();
context.assertIsSatisfied();
}
}
and the runnable that I'm testing:
public class ExecuteGameRunnable implements Runnable {
private BlockingQueue<Game> queue;
private Executor executor;
private Boolean unitTesting = false;
static Logger logger = Logger.getLogger(ExecuteGameRunnable.class);
public ExecuteGameRunnable(BlockingQueue<Game> queue, Executor executor) {
this.queue = queue;
this.executor = executor;
}
public ExecuteGameRunnable (BlockingQueue<Game> queue, Executor executor, Boolean unitTesting) {
this(queue,executor);
this.unitTesting = unitTesting;
}
public void run() {
try {
do {
if (Thread.interrupted()) throw new InterruptedException();
Game game = queue.take();
logger.info("Game "+game.getId()+" taken. Checking if it is processing"); // THIS ONE PRINTS OUT THE GAME ID THAT I RETURN WITH JMOCK-FRAMEWORK
if (game.isProcessing()) {
continue;
}
game.updateProcessing(true);
executor.execute(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
}
});
} while (!unitTesting);
} catch (InterruptedException ex) {
logger.info("Game-Execution-Executor interrupted.");
return;
} catch (DataSourceException ex) {
logger.fatal("Unable to connect to DB whilst executing game: "+id_game,ex);
return;
}
}
}
JMock isn't thread safe. It's intended to support unit testing, rather than what is a very small integration test. Frankly, in this case I'd use a real BlockingQueue rather than a mock one. And there is no way you should have a unitTesting flag in your production code.
One more thing, you don't need to set the fields in the test class to null, jUnit flushes the instance for every test.