Null Pointer Exception in JUnit test case - java

Is there any way to write a mockito test case for the particular case.
public void saveStaffInfo(HttpServletResponse response, RegBean regdata, Staffinfo staffType, boolean status)
throws IOException {
if (status)
{
boolean status1 = staffType.insertlogin(regdata);
if(status1) {
response.sendRedirect("registration.jsp?status=success");
}
else {
response.sendRedirect("registration.jsp?status=login_table_error");
}
} else {
response.sendRedirect("registration.jsp?status=failed");
}
}
I did mock the HttpServeletResponse, RegBean,Staffinfo. However, as it is of void type so I cannot use doReturn().when(mockedMethod).(someMethod). So how do I test these lines?
I also need code coverage. I am very new to this.
The test case
#Test
public void testSaveStaffInfo() throws IOException, ServletException{
boolean status =true;
// System.out.println(iStaffInfo.insertlogin(regdata));
Mockito.when(iStaffInfo.insertlogin(regdata)).thenReturn(Boolean.TRUE );
reg.saveStaffInfo(response, regdata, iStaffInfo,status);
}

You need to think what it is you want to test here. What is the "output"? The "output" here is that the method is doing something to your HttpServletResponse, it is calling sendRedirect.
You can verify that certain methods are being called on your mocked (or real) objects with Mockito.verify

Related

Spring Boot 2 After aspect find success or failure

I am working on Spring Boot 2 to create a microservice. I have a requirement to create an After aspect to execute some piece of code.
#Aspect
#Component
public class FinallyAspect {
#Pointcut("#annotation(finallyEvent)")
public void runFinallyMethod(FinallyEvent finallyEvent) {}
#After("runFinallyMethod(FinallyEvent finallyEvent)")
public void finallyMethod(JoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable {
// ...
}
}
Is it possible to get inside finallyMethod whether an exception has occurred or the method returned successfully? I can do it with #AfterReturning and #AfterThrowing annotation, but if there is a way to check if the method has ended in error or success then I can check it in a single function.
It is not possible with After-advice to access whether the method returned successfully or with an exception. There are alternatives...
a) Around-advice (not recommended)
What you want can be manually implemented with a single method using the Around-advice, the most general kind of advice. It is recommended that you use the least powerful advice type that can implement the required behaviour (source). I do not recommend this approach as it can be error-prone in terms of exception handling if implemented the wrong way. For example, if you put your success-code in the try-block, exceptions thrown by this success-code are also caught by the same catch-block as is used for the failure-code. Also, you need to make sure to re-throw the exception and to return the return value of joinPoint.proceed().
This is how could do this properly if you wanted to:
#Around(value = "runFinallyMethod(finallyEvent)", argNames = "joinPoint,finallyEvent")
public Object finallyMethod(ProceedingJoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable {
final Object res;
try {
res = joinPoint.proceed();
} catch (Throwable e) {
// code in case of failure
throw e;
}
// code in case of success
return res;
}
b) Clean solution with private method
In this case, I suggest to use AfterReturning-advice and AfterThrowing-advice and then call a private method with a parameter indicating success/error. This is much more readable, does not have the drawbacks of the Around-advice but uses a bit more code.
A boolean (success) is needed
#AfterReturning(value = "runFinallyMethod(finallyEvent)", argNames = "joinPoint,finallyEvent")
public void finallyMethodReturning(JoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable {
finallyMethod(joinPoint, finallyEvent, true);
}
#AfterThrowing(value = "runFinallyMethod(finallyEvent)", argNames = "joinPoint,finallyEvent")
public void finallyMethodThrowing(JoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable {
finallyMethod(joinPoint, finallyEvent, false);
}
private void finallyMethod(JoinPoint joinPoint, FinallyEvent finallyEvent, boolean success) throws Throwable {
if (success) {
// code in case of success
} else {
// code in case of failure
}
}
The Throwable is needed
#AfterReturning(value = "runFinallyMethod(finallyEvent)", argNames = "joinPoint,finallyEvent")
public void finallyMethodReturning(JoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable {
finallyMethod(joinPoint, finallyEvent, null);
}
#AfterThrowing(value = "runFinallyMethod(finallyEvent)", throwing = "t", argNames = "joinPoint,finallyEvent,t")
public void finallyMethodThrowing(JoinPoint joinPoint, FinallyEvent finallyEvent, Throwable t) throws Throwable {
finallyMethod(joinPoint, finallyEvent, t);
}
private void finallyMethod(JoinPoint joinPoint, FinallyEvent finallyEvent, Throwable t) throws Throwable {
if (t == null) {
// code in case of success
} else {
// code in case of failure
}
}
I don't think you will be able to implement this using #After as this annotation can only give you the JoinPoint in context, which has no information about return values.
If you want to handle everything within the same method I think the only alternative is to implement this using #Around, where you can do something before and after a method execution. Your implementation could be:
#Around("runFinallyMethod(FinallyEvent finallyEvent)")
public Object finallyMethod(ProceedingJoinPoint jp, FinallyEvent finallyEvent) throws Throwable {
try {
Object result = jp.proceed();
// do nice stuff with result
return result;
} catch(Throwable throwable) {
// do nice stuff with the exception;
throw throwable;
}
}

Junit Asserting failed HTTP post request

I have an HTTPClient test for my spring boot app. I have a class that throws an exception if the a POST request to the server is in a string 2048 bytes or over.
#Component
public class ApplicationRequestSizeLimitFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
System.out.println(request.getContentLength());
if (request.getContentLengthLong() >= 2048) {
throw new IOException("Request content exceeded limit of 2048 bytes");
}
filterChain.doFilter(request, response);
}
}
I created a unit test for it but I am not sure how I can write an assert statement to check if it fails to post the request.
Right now I have this so far in my test class
#Test
public void testSize() throws ClientProtocolException, IOException {
Random r = new Random(123);
long start = System.currentTimeMillis();
String s = "";
for (int i = 0; i < 65536; i++)
s += r.nextInt(2);
String result = Request.Post(mockAddress)
.connectTimeout(2000)
.socketTimeout(2000)
.bodyString(s, ContentType.TEXT_PLAIN)
.execute().returnContent().asString();
}
This test fails which is what I want but I want to create an assert so it passes (assert that it fails the http response due to being over the byte limit).
You can surround the failing part with a try/catch, and call fail() at the end of the try block. If an exception is thrown, the fail() instruction should not be reached, and your test should pass.
#Test has an argument to assert that a particular exception gets thrown, you could write your test like e.g :
#Test(expected = IOException.class)
public void testSize() throws ClientProtocolException, IOException {
...
}
There are 3 ways you can achieve that:
1) Use #Test(expected = ....) annotation where you provide class of exception you want to check.
#Test(expected = IOException.class)
public void test() {
//... your test logic
}
This is not a recommended way of exception testing unless your test is really really small and does one thing only. Otherwise, you may get an IOException thrown but you won't be sure which part of test code exactly caused it.
2) Use #Rule annotation with ExpectedException class:
#Rule
public ExpectedException exceptionRule = ExpectedException.none();
#Test
public void testExpectedException() {
exceptionRule.expect(IOException.class);
exceptionRule.expectMessage("Request too big.");
//... rest of your test logic here
}
Please note that exceptionRule has to be public.
3) And last one, quite old-fashioned way:
#Test
public void test() {
try {
// your test logic
fail(); // if we get to that point it means that exception was not thrown, therefore test should fail.
} catch (IOException e) {
// if we get here, test is successfull and code seems to be ok.
}
}
It's an old fashioned way that adds some unnecessary code to your test that is supposed to be clean.
There is another solution, not already presented in these answers, and is my personal preference. assertThatThrownBy
in your case
#Test
public void testSizeException(){
assertThatThrownBy(()-> Request.Post(mockAddress)
.connectTimeout(2000)
.socketTimeout(2000)
.bodyString(s, ContentType.TEXT_PLAIN)
.execute().returnContent().asString())
.isInstanceOf(IOException.class)
.hasMessageContaining("Request content exceeded limit of 2048
bytes");
}
*Disclaimer, above code written directly into SO editor

Spring Boot passes test case that should fail

I have added a test case in my Spring Boot application. However, when I ./gradlew build, all the test cases pass. Any reason?
#Test
public void testIntentionalError() throws Exception {
boolean thrown = true;
assertThat(!thrown);
}
It's because your test doesn't test anything.
Try this :
#Test
public void testIntentionalError() throws Exception {
boolean thrown = true;
assertTrue(!thrown);
}
you can try something like the following (in case you want to use the assertThat method):
#Test
public void testIntentionalError() throws Exception {
boolean thrown = true;
assertThat(!thrown, is(true));
}
using hamcrest matcher (import static org.hamcrest.core.Is.is)

Should assert be placed in the test case or verification method?

For regression testing (not unit testing), where we have elaborate scenarios written in TestNG, is there a proper place the Assert checks should be done? Does it matter or not if it's in the test case, or in a calling method? For example:
This test case calls a validation method that contains the asserts:
#Test
public void test1() {
validateResponse();
}
public void validateResponse() {
Assert.assertEquals(a, "123");
Assert.assertEquals(b, "455");
Assert.assertEquals(c, "5678");
Assert.assertEquals(d, "3333");
}
This test case asserts based on the return value of the verification method:
#Test
public void test1() {
Assert.assertTrue(validateResponse());
}
public boolean void validateResponse() throws Exception {
try {
if (!a.equals("123")) throw new Exception();
if (!b.equals("455")) throw new Exception();
if (!c.equals("5678")) throw new Exception();
if (!d.equals("3333")) throw new Exception();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
Your assert should be as specific and granular as possible to help the developer quickly identify the problem. e.g.
#Test
public void testResponseFields(){
// create response to be tested
// JUnit style
Assert.assertEquals("Response 'alpha' should be '123'", 123, response.getAlpha());
// TestNG style
Assert.assertEquals(response.getAlpha(), 123, "Response 'alpha' should be '123'");
}
Once you set a failure message in the Assert.assertXX call, it becomes more of a moot point as to where the Assert is called as you will have a message explaining the problem and a stack trace to see where and when it failed.

how to know where HttpServletResponse is redirecting?

I'm taking Software Testing because I'm majoring in CS. The professor gave us the source code of a program made in Java to test it. I'm testing right now this method:
public static void createPanel(HttpServletRequest req, HttpServletResponse res, HttpSession hs) throws IOException
{
String panelName = req.getParameter("panelName");
String panelDescription = req.getParameter("panelDescription");
int employeeID = ((EmployeeProfile)hs.getAttribute("User Profile")).EmployeeID;
boolean result;
//Let's validate our fields
if(panelName.equals("") || panelDescription.equals(""))
result = false;
else
result = DBManager.createPanel(panelName, panelDescription, employeeID);
b = result;
//We'll now display a message indicating the success of the operation to the user
if(result)
res.sendRedirect("messagePage?messageCode=Panel has been successfully created.");
else
res.sendRedirect("errorPage?errorCode=There was an error creating the panel. Please try again.");
}
I'm using Eclipse with JUnit and mockito to test all the methods including this one. For this specific method, I want to check if the program redirects to one location or another, but I don't know how to do it. Do you have any idea? Thanks.
You can actually achieve it easily with Mockito and ArgumentCaptor:
#RunWith(MockitoJUnitRunner.class)
public class MyTest {
#Mock
private HttpServletResponse response
...
#Test
public void testCreatePanelRedirection(){
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
YourClass.createPanel(request, response, session);
verify(response).sendRedirect(captor.capture());
assertEquals("ExpectedURL", captor.getValue());
}
}

Categories

Resources