Mock an exception object (JUnit/Mockito) - java

I am facing an issue testing a legacy code using JUnit/Mockito,
my method throws an exception (HandlerException) which is derived from (BaseException) which is part of our infrastructure.
public class HandlerException extends BaseException
My system-under-test is super simple:
public static void parse(JsonElement record) throws HandlerException
{
JsonElement element = record.getAsJsonObject().get(ID_TAG);
if(element == null) {
throw new HandlerException("Failed to find Id ...");
}
...
}
And also the test itself
#Test (expected=HandlerException.class)
public void testParseg() throws HandlerException {
JsonElement jsonElement = new JsonParser().parse("{}");
Parser.parse(jsonElement);
}
The problem is with BaseException. It is a complex class and depends on an initialization. Without initializing it BaseException throws an exception in its constructor :( which in turn causes StackOverflowException.
Is it possible to Mock BaseException or HandlerException in any way to avoid this initialization keeping my test simple?

Looks like the answer to my issue was using PowerMockito
First I use #PrepareForTest on my system-under-test (Parser.class)
#RunWith(PowerMockRunner.class)
#PrepareForTest({Parser.class})
Then I mocked the HandlerExeption class using PowerMockito.whenNew
#Mock
HandlerException handlerExceptionMock;
#Before
public void setup() throws Exception {
PowerMockito.whenNew(HandlerException.class)
.withAnyArguments().thenReturn(handlerExceptionMock);
}
#Test (expected=HandlerException.class)
public void testParseg() throws HandlerException {
JsonElement jsonElement = new JsonParser().parse("{}");
Parser.parse(jsonElement);
}
This way BaseException was not constructed and my test passed without the need to initialize it.
Note: I am aware that this is not the best practice, however, in my case, I had to since I cannot edit BaseException.

Related

mocking a constructor to see if it throws an exception

Java 8
I have the following constructor I want to test using Mockito.
I want the test to throw an exception if a null is passed for the repository.
public PresenterImp(#Nonnull IRepository repository, IScheduler scheduler) {
super(schedulerFactory);
this.repository = Preconditions.checkNotNull(repository);
}
What would be the best way to do this? As my presenter is not a mock so I can’t use a when..
In my setup I do the following:
#Before
public void setup() throws Exception {
repository = Mockito.mock(IRepository.class);
iScheduler = Mockito.mock(IScheduler.class);
viewContract = Mockito.mock(ViewContract.class);
presenter = new PresenterImp(repository, iScheduler);
optInNotificationPresenter.attachView(viewContract);
}
Many thanks for any suggestions
Can do it as:
#Test(expected=NullPointerException.class )
public void testNullCheck() throws Exception
new PresenterImp(null, mock);
}

mocking nested function is giving NPE

Hi I am getting Null Pointer Exception while trying to write unit test cases
Here is the class detail:
public CreateDraftCampaignResponse createDraftCampaign(CreateDraftCampaignRequest request) throws InvalidInputsException,
DependencyException, UnauthorizedException {
CreateDraftCampaignResponse draftCampaignResponse = null;
try {
DraftCampaignDetails createdDraft = draftCampaignI.createDraftCampaign(ConvertionUtil
.getDraftCampaignDetailsfromCreateDraftRequest(request));
draftCampaignResponse = new CreateDraftCampaignResponse();
draftCampaignResponse.setDraftCampaignId(createdDraft.getDraftId());
}
catch (Exception e) {
log.error("Create Draft Campaign Exception", e);
throw e;
}
return draftCampaignResponse;
}
This is the ConvertionUtil class:
public static DraftCampaignDetails getDraftCampaignDetailsfromCreateDraftRequest(CreateDraftCampaignRequest request) {
DraftCampaignDetails draftCampaign = new DraftCampaignDetails();
DraftCampaignDetailsBase draftCampaignDetailsBase = request
.getDraftCampaignDetailsBase(); (This is giving exception)
draftCampaign.setCampaignBudget(draftCampaignDetailsBase
.getCampaignBudget());
draftCampaign.setCampaignName(draftCampaignDetailsBase
.getCampaignName());
draftCampaign.setDraftCampaignState(draftCampaignDetailsBase
.getDraftCampaignState());
draftCampaign.setCreatedUser(request.getUser());
draftCampaign.setObfuscatedEntityId(request.getObfuscatedEntityId());
draftCampaign.setCampaignInfo(request.getCampaignInfo());
return draftCampaign;
}
Thsi is what I tried:
#Test
public void createDraft_newDraft() {
DraftCampaignActivity draftContoller = new DraftCampaignActivity();
CreateDraftCampaignRequest request = createRequest();
DraftCampaignDetails details = buildDraftDetails();
if(draftCampaignI == null){
System.out.println("sccdscscd");
}
//ConvertionUtil action1 = PowerMockito.mock(ConvertionUtil.class);
//PowerMockito.when(action1.getDraftCampaignDetailsfromCreateDraftRequest(request)).thenReturn(details);
when(util.getDraftCampaignDetailsfromCreateDraftRequest(request)).thenReturn(details);
when(draftCampaignI.createDraftCampaign(details)).thenReturn(details);
CreateDraftCampaignResponse response = new CreateDraftCampaignResponse();
draftContoller.createDraftCampaign(request);
response.setDraftCampaignId(details.getDraftId());
Assert.assertEquals(response.getDraftCampaignId(),"ww");
}
I am getting NPE. I am a novice in Mockito and other framework. Please help!
It doesn't work because you try to mock a static method and you don't do it properly such that it calls the real method which leads to this NPE in your case.
To mock a static method using Powermock, you need to:
Use the #RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
Use the #PrepareForTest(ClassThatContainsStaticMethod.class) annotation at the class-level of the test case.
Use PowerMock.mockStatic(ClassThatContainsStaticMethod.class) to mock all methods of this class.
So in your case, you should have something like:
#RunWith(PowerMockRunner.class)
public class MyTestClass {
#Test
#PrepareForTest(ConvertionUtil.class)
public void createDraft_newDraft() {
...
PowerMockito.mockStatic(ConvertionUtil.class);
PowerMockito.when(
ConvertionUtil.getDraftCampaignDetailsfromCreateDraftRequest(request)
).thenReturn(details);
...
}
More details about How to mock a static method with Powermock.

Mockito method throwing null pointer exception for variable used

Iam using mockito to perform testing and iam very much new to it.
Iam getting a null pointer exception in the Mockito method and in the Onmessage method for the use of a object/variable declared.
The code snippet is as below.
Class A.java
Class A{
#Inject
CheckConnection connection;
public void onMessage(Message m)
{
if(connection.IsInternetavailable==true) //Null pointer is occuring here
{
//Do something with Message
}
else
{
//Do something with Message
}
}
}
Class Atest.java-Mockito Class
Class ATest
{
#InjectMocks
A resource;
#Mock
CheckConnection connection;
#Test
public void shouldProcessMessage() throws JMSException {
// Arrange
final String Type = "MessageType";
final String Body = "MessageBody"
final ActiveMQTextMessage message = new ActiveMQTextMessage();
message.setStringProperty("messageType", Type);
message.setText(Body);
// Act
this.resource.onMessage(message); //This method fails i.e. it gives null pointer exception
}
}
First: the annotation is InjectMocks not InjectMock s is missing
Second: You need to initialize the mocks with this call MockitoAnnotations.initMocks(this); which should be in your set up method or first call in your test method.

How to partial mock a method that throws exceptions using Mockito?

It's useful to test exception handling. In this specific case, I have a extractor that will do a specific task when an exception is thrown while unmarshaling a specific class.
Example Code
Below is a simplified example of the code. The production version is much more complicated.
public class Example {
public static enum EntryType {
TYPE_1,
TYPE_2
}
public static class Thing {
List<String> data = new ArrayList<String>();
EnumSet<EntryType> failedConversions = EnumSet.noneOf(EntryType.class);
}
public static class MyHelper {
public String unmarshal(String input) throws UnmarshalException {
// pretend this does more complicated stuff
return input + " foo ";
}
}
public static class MyService {
MyHelper adapter = new MyHelper();
public Thing process() {
Thing processed = new Thing();
try {
adapter.unmarshal("Type 1");
} catch (UnmarshalException e) {
processed.failedConversions.add(EntryType.TYPE_1);
}
// do some stuff
try {
adapter.unmarshal("Type 2");
} catch (UnmarshalException e) {
processed.failedConversions.add(EntryType.TYPE_2);
}
return processed;
}
}
}
Things I've Tried
Here's a list of things I've tried. For brevity, I haven't filled in all the mundane details.
Spying
The following method doesn't do anything and the exception doesn't throw. I'm not sure why.
#Test
public void shouldFlagFailedConversionUsingSpy()
throws Exception {
MyHelper spied = spy(fixture.adapter);
doThrow(new UnmarshalException("foo")).when(spied).unmarshal(
Mockito.eq("Type 1"));
Thing actual = fixture.process();
assertEquals(1, actual.failedConversions.size());
assertThat(actual.failedConversions.contains(EntryType.TYPE_1), is(true));
}
Mocking
The following didn't work because partial mocks don't seem to play well with methods that throw exceptions.
#Test
public void shouldFlagFailedConversionUsingMocks()
throws Exception {
MyHelper mockAdapter = mock(MyHelper.class);
when(mockAdapter.unmarshal(Mockito.anyString())).thenCallRealMethod();
when(mockAdapter.unmarshal(Mockito.eq("Type 2"))).thenThrow(
new UnmarshalException("foo"));
Thing actual = fixture.process();
assertEquals(1, actual.failedConversions.size());
assertThat(actual.failedConversions.contains(EntryType.TYPE_2), is(true));
}
ThenAnswer
This works, but I'm not sure if it's the proper way to do this:
#Test
public void shouldFlagFailedConversionUsingThenAnswer() throws Exception {
final MyHelper realAdapter = new MyHelper();
MyHelper mockAdapter = mock(MyHelper.class);
fixture.adapter = mockAdapter;
when(mockAdapter.unmarshal(Mockito.anyString())).then(
new Answer<String>() {
#Override
public String answer(InvocationOnMock invocation)
throws Throwable {
Object[] args = invocation.getArguments();
String input = (String) args[0];
if (input.equals("Type 1")) {
throw new UnmarshalException("foo");
}
return realAdapter.unmarshal(input);
}
});
Thing actual = fixture.process();
assertEquals(1, actual.failedConversions.size());
assertThat(actual.failedConversions.contains(EntryType.TYPE_1), is(true));
}
Question
Although the thenAnswer method works, it doesn't seem to be the proper solution. What is the correct way to perform a partial mock for this situation?
I'm not quite sure what you were getting at with the mocking and the spying, but you only really need to mock here.
First, I ran into a few snags when trying your mocks out for whatever reason. I believe this had to do with the spy call which was messed up in some way. I did eventually overcome these, but I wanted to get something simple to pass.
Next, I did notice something off with the way you were spying (the basis of my approach):
MyHelper spied = spy(fixture.adapter);
This implies that you want an instance of MyHelper mocked out, not spied. The worst part is that even if this object were fully hydrated, it wouldn't be properly injected since you haven't reassigned it to the test object (which I presume is fixture).
My preference is to use the MockitoJUnitRunner to help with the injection of mocked instances, and from there I build up a basis of what it is I actually need to mock.
There's only one mocked instance and then the test object, and this declaration will ensure that they're both instantiated and injected:
#RunWith(MockitoJUnitRunner.class)
public class ExampleTest {
#Mock
private MyHelper adapter;
#InjectMocks
private MyService fixture;
}
The idea is that you're injecting your mock into the fixture. You don't have to use this - you could use standard setters in a #Before declaration, but I prefer this since it greatly reduces the boilerplate code you have to write to get mocking to work.
Now there's only one change to be made: remove the spy instance and replace its previous usage with the actual mock.
doThrow(new UnmarshalException("foo")).when(adapter).unmarshal(eq("Type 1"));
With all of the code hoisted, this passes:
#RunWith(MockitoJUnitRunner.class)
public class ExampleTest {
#Mock
private MyHelper adapter;
#InjectMocks
private MyService fixture;
#Test
public void shouldFlagFailedConversionUsingSpy()
throws Exception {
doThrow(new UnmarshalException("foo")).when(adapter).unmarshal(eq("Type 1"));
Thing actual = fixture.process();
assertEquals(1, actual.failedConversions.size());
assertThat(actual.failedConversions.contains(Example.EntryType.TYPE_1), is(true));
}
}
Not being one to want to leave the question/use case incomplete, I circled around and replaced the test with the inner classes, and it works fine too:
#RunWith(MockitoJUnitRunner.class)
public class ExampleTest {
#Mock
private Example.MyHelper adapter;
#InjectMocks
private Example.MyService fixture;
#Test
public void shouldFlagFailedConversionUsingSpy()
throws Exception {
doThrow(new UnmarshalException("foo")).when(adapter).unmarshal(eq("Type 1"));
Example.Thing actual = fixture.process();
assertEquals(1, actual.failedConversions.size());
assertThat(actual.failedConversions.contains(Example.EntryType.TYPE_1), is(true));
}
}

Can junit test that a method will throw an exception?

Could you tell me please, is it normal practice to write a method (example: JUnit Test) that throws an Exception, for example:
class A {
public String f(int param) throws Exception {
if (param == 100500)
throw new Exception();
return "";
}
}
private A object = new A();
#Test
public void testSomething() throws Exception {
String expected = "";
assertEquals(object.f(5), expected);
}
In fact, method f() won't throw an exception for that parameter(5) but nevertheless I must declare that exception.
Yes it is completely fine, and if it does throw the exception the test will be considered as failed.
You need to specify that the method throws an Exception even if you know that the specific case does not (this check is done by the compiler).
In this case, what you expect is object.f(5) returns an empty string. Any other outcome (non-empty string or throwing an exception) would result in a failed test case.
A JUnit-Test is meant to test a given method for correct behavior. It is a perfectly valid scenario that the tested method throws an error (e.g. on wrong parameters). If it is a checked exception, you either have to add it to your test method declaration or catch it in the method and Assert to false (if the exception should not occur).
You can use the expected field in the #Test annotation, to tell JUnit that this test should pass if the exception occurs.
#Test(expected = Exception.class)
public void testSomething() throws Exception {
String expected = "";
assertEquals(object.f(5), expected);
}
In this case, the tested method should throw an exception, so the test will pass. If you remove the expected = Exception.class from the annotation, the test will fail if an exception occurs.
If the method you're calling throws a checked exception yes, you'll either need a try catch or to rethrow. It's fine to do this from the test itself. There are a variety of ways to test Exception using JUnit. I've tried to provide a brief summary below:
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
/**
* Example uses Kent Beck - Test Driven Development style test naming
* conventions
*/
public class StackOverflowExample {
#Rule
public ExpectedException expectedException = ExpectedException.none();
#Test
// Note the checked exception makes us re-throw or try / catch (we're
// re-throwing in this case)
public void calling_a_method_which_throws_a_checked_exception_which_wont_be_thrown() throws Exception {
throwCheckedException(false);
}
/*
* Put the class of the specific Exception you're looking to trigger in the
* annotation below. Note the test would fail if it weren't for the expected
* annotation.
*/
#Test(expected = Exception.class)
public void calling_a_method_which_throws_a_checked_exception_which_will_be_thrown_and_asserting_the_type()
throws Exception {
throwCheckedException(true);
}
/*
* Using ExpectedException we can also test for the message. This is my
* preferred method.
*/
#Test
public void calling_a_method_which_throws_a_checked_exception_which_will_be_thrown_and_asserting_the_type_and_message()
throws Exception {
expectedException.expect(Exception.class);
expectedException.expectMessage("Stack overflow example: checkedExceptionThrower");
throwCheckedException(true);
}
// Note we don't need to rethrow, or try / catch as the Exception is
// unchecked.
#Test
public void calling_a_method_which_throws_an_unchecked_exception() {
expectedException.expect(Exception.class);
expectedException.expectMessage("Stack overflow example: uncheckedExceptionThrower");
throwUncheckedException();
}
private void throwCheckedException(boolean willThrow) throws Exception {
// Exception is a checked Exception
if (willThrow) {
throw new Exception("Stack overflow example: checkedExceptionThrower");
}
}
private void throwUncheckedException() throws NullPointerException {
// NullPointerException is an unchecked Exception
throw new NullPointerException("Stack overflow example: uncheckedExceptionThrower");
}
}
You can test that the exception is launched with this:
#Test(expected = ValidationException.class)
public void testGreaterEqual() throws ValidationException {
Validate.greaterEqual(new Float(-5), 0f, "error7");
}

Categories