Is there a way to test two opposite methods in JUnit 5? - java

I have two opposite methods that I have to test
First method
private boolean isGeoOrtInboundPortabilityToNonGeoSipFiber(Character oldNdipAffectation,
Character newNdipAffectation) {
return isNdip09NatifVoipSip(newNdipAffectation)
&& isNdipGeoOperator(oldNdipAffectation);
}
Second method
private boolean isNonGeoSipOutboundPortabilityToGeoFiberOrt(Character oldNdipAffectation,
Character newNdipAffectation) {
return isNdipGeoOperator(newNdipAffectation)
&& isNdip09NatifVoipSip(oldNdipAffectation);
}
Here is the implementation
protected void checkRenumberingValidation(Character oldNdipAffectation,
NdipRenumberingRequest request, String basicatCode) {
var oldNdipIndicatif = findIndicatifByNd(request.getOldNdip());
var newNdipIndicatif = findIndicatifByNd(request.getNewNdip());
if (!isClassicIpPortedNds(request)
|| !isGeoOrtInboundPortabilityToNonGeoSipFiber(oldNdipAffectation, newNdipAffectation)
|| !isNonGeoSipOutboundPortabilityToGeoFiberOrt(oldNdipAffectation, newNdipAffectation)
|| !isRtcPortabilityToFiberSip(newNdipIndicatif, oldNdipAffectation, newNdipAffectation,
basicatCode)
&& (
!Objects.equals(newNdipIndicatif.getZne().getCzne(), oldNdipIndicatif.getZne().getCzne())
|| !Objects.equals(newNdipIndicatif.getCsitugeo(), oldNdipIndicatif.getCsitugeo()))
) {
throwFunctionalException(ERROR_34);
}
}
If I pass 'D' and 'P' this will cause throwFunctionalException(ERROR_34) and that is fine
!isGeoOrtInboundPortabilityToNonGeoSipFiber('D', 'P') // Throw exception which is expected
The problem is the isRtcPortabilityToFiberSip() method is never reached because if I pass 'P' and 'D'
!isGeoOrtInboundPortabilityToNonGeoSipFiber('P', 'D') // Pass
isNonGeoSipOutboundPortabilityToGeoFiberOrt('P', 'D') // Throw exception which is expected
!isRtcPortabilityToFiberSip(newNdipIndicatif, oldNdipAffectation, newNdipAffectation,
basicatCode) // never reached
How to reach !isRtcPortabilityToFiberSip with JUnit 5?
I googled the problem without any solution.

You ought to have three different test functions:
#Test
public void testIsGeoOrtInboundPortabilityToNonGeoSipFiber() throws Exception
{
!isGeoOrtInboundPortabilityToNonGeoSipFiber('P', 'D') // Pass
}
#Test(expected = Exception.class)
public void testIsNonGeoSipOutboundPortabilityToGeoFiberOrt() throws Exception
{
isNonGeoSipOutboundPortabilityToGeoFiberOrt('P', 'D') // Throw exception which is expected
}
#Test
public void testIsRtcPortabilityToFiberSip() throws Exception
{
!isRtcPortabilityToFiberSip(newNdipIndicatif, oldNdipAffectation, newNdipAffectation,
basicatCode) // never reached, but now it will be!
}
A good practice is to have one assertion per test (although this is flexible)
Your code does not really have assertions (they could be added by having checkRenumberingValidation return a boolean value, instead of throwing an exception when objects are not equal), but the conditions are being checked adequately, just in a more roundabout way than usual.
For more reading about testing, I highly recommend the JUnit FAQ
(written when JUnit 4 was current, but nearly all concepts can be applied generally -- this is a classic)

Related

What do i do to create a unit test for the code below

public String getBloodPressureLevel() {
if (this.systolic > MedicalRecord.AT_RISK_SYSTOLIC_UPPER_BOUND
|| this.diastolic > MedicalRecord.AT_RISK_DIASTOLIC_UPPER_BOUND) {
return "High";
} else if ((this.systolic >= MedicalRecord.AT_RISK_SYSTOLIC_LOWER_BOUND
&& this.systolic <= MedicalRecord.AT_RISK_SYSTOLIC_UPPER_BOUND)
|| (this.diastolic >= MedicalRecord.AT_RISK_DIASTOLIC_LOWER_BOUND
&& this.diastolic <= MedicalRecord.AT_RISK_DIASTOLIC_UPPER_BOUND)) {
return "At risk";
} else {
return "Normal";
}
}
Test cases i'm supposed to have
i'm just not sure how to go about this
You start by reading a tutorial on how JUnit works, for example this here.
Then you think about the different corners of your production code, to then do things like
#Test
public void testForHigh() {
YourClass underTest = new YourClass(/*systolic*/ 200, /*diastolic*/ 100);
assertThat(underTest.getBloodPressureLevel(), is("High"));
}
( where is() is a hamcrest matcher, allowing to write more human readable test conditions and where I assume that you have some class that gets instantiated using a systolic and diastolic data point )
The real point here is: you have to research the tools you are supposed to use, and then you go and implement at least one method for each possible condition, representing the 11 different tests in your input.
( And no, I am not going to give you more code. The above is meant as inspiration to enable you to do this work yourself. )

If we use assertEquals, is it worth to make a check for assertNotNull first in Junit test cases?

I have a test cases as below:
#Test
public void GIVEN_correct_tradingStatusId_parameter_WHEN_invoked_getTradingStatusByName_THEN_correct_TradingStatus_is_returned() {
String tradingStatus = lookupDto.getTradingStatusByName("2013");
assertNotNull(tradingStatus);
assertEquals("Dissolved", tradingStatus);
}
Here I am testing for tradingStatus not to be null and then checking it equals to Dissolved.
My concern is do I actually need to test assertNotNull if I am testing using assertEquals.
I went through the method definition for assertEquals in sourcecode. It is as below:-
static public void assertEquals(String message, Object expected,
Object actual) {
if (equalsRegardingNull(expected, actual)) {
return;
} else if (expected instanceof String && actual instanceof String) {
String cleanMessage = message == null ? "" : message;
throw new ComparisonFailure(cleanMessage, (String) expected,
(String) actual);
} else {
failNotEquals(message, expected, actual);
}
}
In this equalsRegardingNull is like :
private static boolean equalsRegardingNull(Object expected, Object actual) {
if (expected == null) {
return actual == null;
}
return isEquals(expected, actual);
}
I am not able to understand even from this whether it is worth to use assertNotNull before calling assertEquals. Please help.
The short answer is NO.
No there is no need to use assertNotNull before assertEquals. If your tradingStatus is null the comparison will anyway fail and will tell you that you are comparing against null. Everything else makes your test code just more complex but brings no extra benefit in return.
You should try to dig deep isEqual method, you will find:
private static boolean isEquals(Object expected, Object actual) {
return expected.equals(actual);
}
so you will find it's comparing by using expected.equals method, and since expected checks null firstly, by:
if (expected == null) {
return actual == null;
}
and it avoids the NullPointerException in expected.equals, it's safe to compare.
So it's unnecessary to manually check actual(tradingStatus) null by assertNotNull(tradingStatus);.

SonarQube - boolean logic correctness -

I have a problem with the logic expression on my method matches1().
Problem
SonarQube is telling me there is an error:
(expectedGlobalRule == null && actual != null)
SonarQube:
Change this condition so that it does not always evaluate to
"true".
Conditions should not unconditionally evaluate to "TRUE" or to "FALSE"
I'm essentially doing this logic to avoid a NPE on my "Block to be executed".
My code
matches1()
private boolean matches1(GbRule actual, GbRule expected) {
if(actual == null && expected == null) {
return true;
} else if((expected == null && actual != null) || (expected != null && actual == null)) {
return false;
} else {
//Block to be executed
}
}
I inverted the logic in to see what SonarQube would tell me and he doesn't complain about it.
matches2()
private boolean matches2(GbRule actual, GbRule expected) {
if(actual == null && expected == null) {
return true;
} else if(expected != null && actual != null) {
//Block to be executed
} else {
return false;
}
}
Question
Do the problem is in my boolean logic or it's SonarQube that lost
his mind?
If the problem is within sonarQube, how could I resolve it?
The problem is in your logic. Let's take it piece by piece:
if(actual == null && expected == null) {
return true;
At this point if both vars are null then we're no longer in the method. So if we get any further, then at least one of them is non-null.
The viable options at this point are:
actual = null, expected = non-null
actual = non-null, expected = null
actual = non-null, expected = non-null
Now, let's look at the next bit of code:
} else if((expected == null && actual != null)
We already know that both variables can't be null, so as soon as we know expected == null, there's no need to test whether actual != null. That has already been proven by the fact that we got this far. So actual != null is always true, which is why an issue is raised.
Edit
This means that your code could be boiled down to:
private boolean matches1(GbRule actual, GbRule expected) {
if(actual == null && expected == null) {
return true;
} else if(actual == null || expected == null) {
return false;
}
//Block to be executed
}
Note that the else isn't needed & dropping it makes the code easier to read.
Even when the code is correct; seriously, it makes my eyes hurt. Thing is: it is hard to read. Such kind of nested conditions is something that one should not be writing in the first place.
If you can't avoid it; at least refactor it into something like
private boolean areActualAnedExpectedBothNull(args ...) {
return actual == null && expectedGlobalRule == null;
}
And please note; you can dramatically simply your code:
if (areActualAnedExpectedBothNull(actual, expected)) {
return true;
}
if (actual == null) {
return false;
}
if (expected == null) {
return false;
}
do your thing ...
and use such methods in your other code. And of course, you do a lot of unit testing; probably with coverage measurements; just to make sure that your tests really test all possible paths through this maze.
But as said; you better step back and think if there are ways to avoid writing such code in the first place.
The typical answer to booleans, and if/else chains in OO programming is polymorphism. So instead of asking something about its state; you turn to interfaces/abstract classes; and have different implementations of those. And then you have a factory giving you that implementation you need; and then you just call methods on that; without further need for if/else/whatever.
If you don't know what I am talking about - watch these videos; especially the second one!
The problem is with SonarQube.
See this article for more info on ignoring that issue: https://www.bsi-software.com/en/scout-blog/article/ignore-issues-on-multiple-criteria-in-sonarqube.html
You can just set it up to ignore that error within that file.
The gist of it is
Open the Settings (SonarQube General Settings or project Settings) and
select the Exclusions category. Switch to the Issues Exclusions and
scroll down to “Ignore Issues on Multiple Criteria”. Set squid:S00112
as Rule Key Pattern and **/*Activator.java as File Path Pattern.
You will need to change the rule key pattern to the pattern associated with the rule that is being violated for your code and the file pattern as the path of your .java file.

How avoid multiple IF loops in Java [duplicate]

This question already has answers here:
Avoiding NullPointerException in Java
(66 answers)
Closed 9 years ago.
What is the best way to avoid multiple if blocks which is used for null checks in Java?
The following is my sample code. Which one is the most optimized way?
if (address!=null} {
if (firstName!=null) {
if (lastName!=null) {
}
}
}
Use &&. && is logical and. && combines two values and returns a boolean which is true if and only if both of its operands are true
if(address!=null && firstName!=null && lastName!=null)
{
}
For instance
boolean b;
b = 3 > 2 && 5 < 7; // b is true
b = 2 > 3 && 5 < 7; // b is now false
if loop is a wrong word. You should say if statements As in you case you can use OR (||) or AND (&&)statement like this
if(address!=null && firstName!=null && lastName!=null)
{
}
Try AND(&&) if you want to pass all checks or intead of nested if statements and try OR(||) for non nested like else if or simply say if you want to pass anyone of your condition But
if all of these are Strings then you should try like this
"yourValue".equals(stringValue)This will skip the null check.
Use and operator (&&)
if(address!=null && firstName!=null && lastName!=null)
{
//DoSomething here
}
And I suggest you to see Short circuit evaluation
there are no if LOOPS
boolean complete = address != null && firstName != null && lastName != null;
if (complete)
{
}
What about:
public boolean notNulls(Object ... args) {
for(Object arg : args)
if (arg == null) return false;
return true;
}
Use:
if (notNulls(address, firstName, lastName)) {
// do something
}
As others point out, a logical and (&&) is probably the best way to consolidate your logic. An && operation will only evaluate to true if both sides evaluate to true.
if (address != null && firstName != null && lastName != null) {
// Whatever you want to do with that...
} else {
// Whatever you want to do with bad input
}
For the sake of diversity, you could also use a try-catch approach. In Java, a NullPointerException will be thrown if you try to call a method on a null value, which you can catch and handle.
try {
// Whatever you want to do with that...
} catch (NullPointerException npe) {
// Whatever you want to do with bad input
}
This approach can be helpful if you've got a really big set of inputs that might be null, although in general I wouldn't advocate it. (The problem with the second approach is that if you call some other method from the try part that triggers a NullPointerException, it will end up in the catch block here, even though it may be totally unrelated to these inputs - i.e. you could make it hard for yourself to spot a bug in a different part of your program.)

when to throw exception if illegal argument passed to an API method?

See the two examples below. Assume both classes contains public methods belonging to a widely used API library.
AClass.java is easier to write (maybe easier to read due to less noise), but when error is detected, the first method in stack trace is an internal method (nullCheck(...)) and the exception message is not referring to that method. Could this cause unnecessary confusion to the user? I mean in the sense of the user thinking: "it's an internal method which has thrown an exception, must be a bug in the library, not a fault in my program. What a ** useless library..."
BClass.java is more tiresome to write (with all its if statements), but when error is detected the first line of the stack trace pinpoints the API method (called by user) where error was first detected. Would this more likely make user think: "I'm calling that method from my code, must be something wrong with the parameter I'm passing in".
Which would be the preferred way of throwing exception when checking parameters for validity in a public API? Or are the two examples considered equal?
public class AClass {
public void publicApiMethod1(String a){
nullCheck(a, "a");
// do something...
}
public void publicApiMethod2(String a, String b, String c){
nullCheck(a, "a");
nullCheck(b, "b");
nullCheck(c, "c");
// do something...
}
private void nullCheck(Object a, String argName) {
if(a == null){
throw new NullPointerException("Null argument: " + argName);
}
}
}
public class BClass {
public void publicApiMethod1(String a){
if(a == null){
throw new NullPointerException("Null argument: 'a'");
}
// do something...
}
public void publicApiMethod2(String a, String b, String c){
if(a == null){
throw new NullPointerException("Null argument: 'a'");
}
if(b == null){
throw new NullPointerException("Null argument: 'b'");
}
if(c == null){
throw new NullPointerException("Null argument: 'c'");
}
// do something...
}
}
If your error message is descriptive (and it is), no one will bother to look at the stack trace. Thus the first form is better because it encapsulates the validation logic.
Note that there are plenty of assertion methods in various libraries ready to use, see: Objects.requireNonNull and Validate.notNull).
I would do it that way, basically based on your AClass:
public void publicApiMethod2(String a, String b, String c){
try {
nullCheck(a, "a");
nullCheck(b, "b");
nullCheck(c, "c");
}
// catch the NullPointerException,
// and any other Exception explicitly thrown by your validation methods
catch (NullPointerException e) {
throw new IllegalArgumentException(e.getMessage());
}
// do something...
}
That way, the user gets an explicit message and a stacktrace that points to the public method.
in your b class why dont you use
if( (c == null)|| (b == null)|| (a == null) ){
//thrown my red ball
}
less tiresome, more readable
I would think that Class A is fine, as long as you clearly document it with a #throws. I have seen plenty of libraries that will throw deeper in the stack. The important thing is for the user to understand WHY an error was thrown and what they can do to avoid it.

Categories