how do i test instances in junit? [duplicate] - java

This question already has answers here:
How to write a Unit Test?
(5 answers)
Closed 4 years ago.
Below is the code I want to test
public class EPATestMode {
public static final int INVALID_MPG = -1;
private int odometerAtReset;
public EPATestMode() {
odometerAtReset = 0;
}
public void resetReadings(int milesDriven) {
// Use the current mileage as the new baseline
odometerAtReset = milesDriven;
}
public double mpg(int currentOdometer, int gallonsBurnt) {
if (gallonsBurnt == 0) {
return INVALID_MPG;
} else {
int milesDriven = currentOdometer - odometerAtReset;
return milesDriven / gallonsBurnt;
}
}
}
This is my first testcase I want to do , on the instance variable INvalid MPG but when I do this , there is a line crossing out "assertEquals". Very confused about this.(Also new to JUnit testing)
#Test
public void testInvalidMpg() {
EPATestMode MpgTest = new EPATestMode();
double results=MpgTest.INVALID_MPG;
assertEquals(results,-1)
}

You don't state your environment, but most likely it behaves similar to Eclipse (maybe it is Eclipse?) in that a line through the code is an indication that you're using a deprecated API. In this case, if you go to the Junit API documentation, you'll see that assertEquals for doubles like you are calling is deprecated in favor of one that includes a delta. API
The idea is that floating point numbers are inherently inexact, and so comparing them is inexact at best. You need to also include a delta so that you can indicate how far apart the numbers can be and still be acceptable.
So basically you want:
assertEquals(results, -1, .000001); // For example.
On a side note, I understand that you're just trying to wrap your head around this - and consequently you're probably trying to come up with a simple test just to get "something working". But tests like that - where you compare a class constant to see if it's what you input - aren't particularly useful. I would be more inclined to test to make sure that supplying 0 as your "gallons burnt" returns the proper "INVALID_MPG" constant.

Line crossing out means the method is deprecated. http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(double, double)
The new method to use is below
public static void assertEquals(double expected,
double actual,
double delta)
The delta is how much difference the actual and expected can have.

Related

How to use correctly assertThrows on set of values?

I've been learning Java just for a bit, so please advise how exception throwing test should look like in this case?
I have following Gambling Machine Class. And then 2 tests for it. I do not really know what should follow the "Integer" in second method (shouldThrowWhenNumbersOutOfRange). Could you please advise as to the exact syntax?
public class GamblingMachine {
public int howManyWins(Set<Integer> userNumbers) throws InvalidNumbersException {
validateNumbers(userNumbers);
Set<Integer> computerNumbers = generateComputerNumbers();
int count = 0;
for (Integer number : userNumbers) {
if (computerNumbers.contains(number)) {
count++;
}
}
return count;
}
private void validateNumbers(Set<Integer> numbers) throws InvalidNumbersException {
if (numbers.size() != 6) {
throw new InvalidNumbersException();
}
if (numbers.stream().anyMatch(number -> number < 1 || number > 49)) { //anyMatch-function to check whether any element in list satisfy given condition
throw new InvalidNumbersException();
}
}
private Set<Integer> generateComputerNumbers() {
Set<Integer> numbers = new HashSet<>();
Random generator = new Random();
while(numbers.size() < 6) {
numbers.add(generator.nextInt(49) + 1);
}
return numbers;
}
}
private GamblingMachine machine = new GamblingMachine();
#ParameterizedTest
#NullAndEmptySource
public void shouldThrowWhenNumbersEmpty(Set<Integer> numbers) throws InvalidNumbersException {
Assertions.assertThrows(NumberFormatException.class, () -> {
Integer.parseInt(" ");
});
}
#ParameterizedTest
#CsvFileSource(resources ="/numbersOutOfRange.cvs", numLinesToSkip = 1)
public void shouldThrowWhenNumbersOutOfRange(Set<Integer> numbers) throws InvalidNumbersException {
Assertions.assertThrows(NumberFormatException.class, () -> {
Integer. //how code should look like here?
});
}
The point of a test is to, you know, test something. Your shouldThrowWhenNumbersEmpty test doesn't do that (well, it tests that Integer.parseInt(" ") throws something. It does, of course. You... don't have to test the core libraries).
In other words, your gambling machine tests need to be calling some stuff from your GamblingMachine class. The idea is to test GamblingMachine. Not to test Integer.parseInt.
It's also a bizarre test: Why in the blazes is shouldThrowWhenNumbersEmpty parameterized? I assume the point of that test is: "Ensure that the gambling machine works as designed when passing an empty set of numbers in, specifically, the part of the design that states that an InvalidNumbersException is thrown if you do that".
Which is done with something like:
#Test
public void shouldThrowWhenNumbersEmpty() {
Assertions.assertThrows(InvalidNumbersException.class, () -> {
Set<Integer> empty = Set.of();
machine.howManyWins(empty);
});
}
Parameterized tests are a fairly exotic concept. Your test setup appears to be falling into a trap: It appears to be set up that you repeat all the logic that is already in your gamblingmachine class, to then apply this logic to the incoming (parameterized) data, figure out what your gambling machine ought to be doing, and then double check its work.
That's not how you should write tests. Tests focus on a specific result. Parameterized tests can make sense, but only if the stuff you have to do for any given input is roughly the same. For example:
Good use of parameterized testing
You have a csv file containing a bunch of lines, each of which has 6 rolls + the correct answer. Your parameterized test treats each line the same: Call howManyWins using the 6 rolls as input, then check that howManyWins returns the expected value.
Bad use of parameterized testing
You have a csv file containing a bunch of lines, each of which has 6 rolls. Your parameterized test will calculate the right result for the rolls, then invoke gambling machine, and check that the gambling machine gives the same answer as what you calculated.
This is bad: You're just repeating the code. It also means your test code is itself doing more than the very basics (it's doing a bunch of business logic), thus raising the question: Who tests your test, then?
Both of your test methods seem like they should NOT be parameterized, unless that csv also contains results.

Java 8: get average of more than one attribute [duplicate]

This question already has answers here:
How to compute average of multiple numbers in sequence using Java 8 lambda
(7 answers)
Closed 6 years ago.
In the following class:
I want to get average of foo and bar in List<HelloWorld> helloWorldList
#Data
public class HelloWorld {
private Long foo;
private Long bar;
}
OPTION 1: JAVA
Long fooSum, barSum;
for(HelloWorld hw: helloWorldList){
fooSum += hw.getFoo();
barSum += hw.getBar();
}
Long fooAvg = fooSum/helloWorldList.size();
Long barAvg = barSum/helloWorldList.size();
OPTION 2 : JAVA 8
Double fooAvg = helloWorldList.stream().mapToLong(HelloWorld::foo).average().orElse(null);
Double barAvg = helloWorldList.stream().mapToLong(HelloWorld::bar).average().orElse(null);
Which approach is better ?
Is there any better way to get these values ?
Answer edit: This question has been marked duplicate but after reading comments from bradimus i ended up implementing this:
import java.util.function.Consumer;
public class HelloWorldSummaryStatistics implements Consumer<HelloWorld> {
#Getter
private int fooTotal = 0;
#Getter
private int barTotal = 0;
#Getter
private int count = 0;
public HelloWorldSummaryStatistics() {
}
#Override
public void accept(HelloWorld helloWorld) {
fooTotal += helloWorld.getFoo();
barTotal += helloWorld.getBar();
count++;
}
public void combine(HelloWorldSummaryStatistics other) {
fooTotal += other.fooTotal;
barTotal += other.barTotal;
count += other.count;
}
public final double getFooAverage() {
return getCount() > 0 ? (double) getFooTotal() / getCount() : 0.0d;
}
public final double getBarAverage() {
return getCount() > 0 ? (double) getBarTotal() / getCount() : 0.0d;
}
#Override
public String toString() {
return String.format(
"%s{count=%d, fooAverage=%f, barAverage=%f}",
this.getClass().getSimpleName(),
getCount(),
getFooAverage(),
getBarAverage());
}
}
Main Class:
HelloWorld a = new HelloWorld(5L, 1L);
HelloWorld b = new HelloWorld(5L, 2L);
HelloWorld c = new HelloWorld(5L, 4L);
List<HelloWorld> hwList = Arrays.asList(a, b, c);
HelloWorldSummaryStatistics helloWorldSummaryStatistics = hwList.stream()
.collect(HelloWorldSummaryStatistics::new, HelloWorldSummaryStatistics::accept, HelloWorldSummaryStatistics::combine);
System.out.println(helloWorldSummaryStatistics);
Note: As suggested by others if you need high precision BigInteger etc can be used.
The answers/comments you got so far don't mention one advantage of a streams-based solution: just by changing stream() to parallelStream() you could turn the whole thing into a multi-threaded solution.
Try doing that with "option 1"; and see how much work it would need.
But of course, that would mean even more "overhead" in terms of "things going on behind the covers costing CPU cycles"; but if you are talking about large datasets it might actually benefit you.
At least you could very easily see how turning on parallelStreams() would influence execution time!
If you want to find average value in list of integers it is better to use classic approach with iterating.
Streams have some overhead and JVM has to load classes for stream usage. But also JVM has JIT with lots of optimizations.
Please beware of incorrect banchmarking. Use JMH
Streams are good and effective when your iteration operation is not such a simple thing as two integers sum.
Also streams allow you to parallelize code. There is no direct criteria when parallelize is better than single thread. As for me - if function call takes over 100ms - you can parrallelize it.
So, if your dataset processing takes >100ms try parallelStream
If not - use iterating.
P.S. Doug Lea - "When to use parallel streams"
Which approach is better ?
When you say "better", do you mean "closer to the sample's true average" or "more efficient" or what? If efficiency is your goal, streams entail a fair amount of overhead that is often ignored. However, they provide readability and conciser code. It depends upon what you're trying to maximize, how large your datasets are, etc.
Perhaps rephrase the question?

AspectJ creates plenty of methods on pointcut

I am new to AOP (using AspectJ / ajc) and have searched / googled the internet high and low searching for an answer to my puzzle. Hopefully, someone here might have it.
As I was given to understand by the documentation, AspectJ is suppose to inject code. From my experience, however, it seems like it is mostly adding code (and simply makes an exchange of method calls).
For example, if I have the method:
private static int foo() {
System.out.println("Hello world");
return 1;
}
And I define the following around advice for it (with a dummy random in order to manipulate proceed() vs. some other return value):
pointcut foo() : call(int com.mytest.aspects.HelloWorld.foo(..));
int around() : foo() {
System.out.println("around()");
if (System.currentTimeMillis() % 2 == 0)
return proceed();
return 0;
}
I get the following after decompiling using jd-gui:
private static final int foo_aroundBody0()
{
return foo();
}
public static void main(String[] args)
{
foo_aroundBody1$advice(HelloAspect.aspectOf(), null);
}
private static final int foo_aroundBody1$advice(HelloAspect ajc$aspectInstance, AroundClosure ajc$aroundClosure)
{
System.out.println("around()");
if (System.currentTimeMillis() % 2L == 0L)
{
AroundClosure localAroundClosure = ajc$aroundClosure;return foo_aroundBody0();
}
return 0;
}
private static int foo()
{
System.out.println("Hello world");
return 1;
}
If that right? Am I perhaps doing something wrong?
I tried using ajc with my android application, but thanks to some jars and SDKs, I got to the dreaded "too many methods" problem.
I am using call pointcuts for most of the time, however it seems that these extra methods are added for each call, even if done within the same class and method, thus increasing my code size and method count significantly.
Any help understanding if this is correct and how it works will be greatly appreciated!
Your understanding is about correct. If you want to avoid too many methods being created, use execution() pointcuts instead of call() wherever possible, because then only one synthetic method per callee will be created, not per caller. I.e. if one method is called from 25 different places, only one additional method will be created instead of 25.
Furthermore you can avoid overhead by limiting the weaving scope of your aspects to the really needed joinpoints. Most aspects I see weave into way too many places. Also, if before() or after() is sufficient, avoid around().

How to check Type Ranges with Java development tools (JDT)?

I want to parse a String, which contains a number, using JDT to find out whether the contained number is inside the valid Range of one of the Primitive Types.
Let's say i got a float value like this as String "1.7976931348623157e350" and want to see whether it is still inside the allowed range for primitive type 'double'. (In this case it would not be inside the valid range, because the maximum exponent of double is 308).
I don't want to use the standard methods like : Double.parseDouble("1.7976931348623157e350"), because I'm afraid it might be too slow if I have a big amount of primitive types, which I want to check .
If you know the Eclipse development environment you will know that inside a normal java file, eclipse is able to tell whether a variable is out of range or not, by underlining it red, in the the case of 'out of range'. So basically i want to use this functionality. But as you can guess - it's easier said then done!
I have started experimenting with the ASTParser from this library: org.eclipse.jdt.core.dom
But I must admit I was not very successful here.
First i tried calling some of those vistor methods using methods like:
resolveBinding() , but they always only returned me "Null".
I have found some interesting class called ASTSyntaxErrorPropagator , but i'm not sure how this is used correctly. It seems to propagate parsing problems or something like that and gets it's information delivered by some thing class called CodeSnippetParsingUtil I assume. Anyways, these are only speculations.
Does anyone know how to use this ASTParser correctly?
I would be really thankful for some advice.
Here is some basic code-snipped which I tried to debug:
public class DatatypesParser {
public static void main(String[] args) {
ASTParser parser = ASTParser.newParser(AST.JLS4);
Map options = JavaCore.getOptions();
JavaCore.setComplianceOptions(JavaCore.VERSION_1_7, options);
String statement = new String("int i = " + Long.MAX_VALUE + ";");
parser.setSource(statement.toCharArray());
parser.setKind(ASTParser.K_STATEMENTS);
parser.setResolveBindings(true);
parser.setBindingsRecovery(true);
ASTNode ast = parser.createAST(null);
ast.accept(new ASTVisitor() {
#Override
public boolean visit(VariableDeclarationStatement node) {
CodeSnippetParsingUtil util = new CodeSnippetParsingUtil();
return true;
}
});
}
I don't want to use the standard methods like :
Double.parseDouble("1.7976931348623157e350"), because i'm afraid it
might be too slow if i have a big amount of primitive types, which i
want to check .
Under the hood JDT is actually using the standard methods of Double to parse the value, and quite a bit more - so you should always use the standard methods if performance is a concern.
Here is how the double gets parsed by JDT.
From org.eclipse.jdt.internal.compiler.ast.DoubleLiteral:
public void computeConstant() {
Double computedValue;
[...]
try {
computedValue = Double.valueOf(String.valueOf(this.source));
} catch (NumberFormatException e) {
[...]
return;
}
final double doubleValue = computedValue.doubleValue();
if (doubleValue > Double.MAX_VALUE) {
// error: the number is too large to represent
return;
}
[...]
}

BigDecimal.valueOf caching mechanism

I heard that the BigDecimal.valueOf() method is better than calling new BigDecimal() because it caches common values. I wanted to know how the caching mechanism of valueOf works.
Looking at the JDK 1.8 sources, it looks like it's just a static array which is initialized as part of class initialization - it only caches the values 0 to 10 inclusive, but that's an implementation detail. For example, given dasblinkenlight's post, it looks like earlier versions only cached 0 and 1.
For more detail - and to make sure you're getting information about the JDK which you're actually running - look at the source of the JDK you're using for yourself - most IDEs will open the relevant source code automatically, if they detect the source archive has been included in your JDK installation. Of course, if you're using a different JRE at execution time, you'd need to validate that too.
It's easy to tell whether or not a value has been cached, based on reference equality. Here's a short but complete program which finds the first non-negative value which isn't cached:
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
for (long x = 0; x < Long.MAX_VALUE; x++) {
if (BigDecimal.valueOf(x) != BigDecimal.valueOf(x)) {
System.out.println("Value for " + x + " wasn't cached");
break;
}
}
}
}
On my machine with Java 8, the output is:
Value for 11 wasn't cached
Of course, an implementation could always cache the most recently requested value, in which case the above code would run for a very long time and then finish with no output...
If I m not wrong it caches only zero,one, two and ten, Thats why we have only
public static final BigInteger ZERO = new BigInteger(new int[0], 0);
public static final BigInteger ONE = valueOf(1);
private static final BigInteger TWO = valueOf(2);
public static final BigInteger TEN = valueOf(10);
That also calls valueOf(x) method.

Categories