Simplest way to unit test an android library application? - java

Sorry if this is a bit of a vague question, however im struggling to find a single solid example on how to do unit testing (isolated testing) with Android...
Here is an example of what i'm wanting to achieve:
// Some class
class Calculator
{
public int Add(int a, int b) { return a+b; }
}
// Simple test
import org.junit.Assert;
import org.junit.Test;
class CalculatorTests
{
#Test
public void should_add_numbers_correctly()
{
Calculator calculator = new Calculator();
int expectedResult = 5 + 5;
int actualResult = calculator.Add(5,5);
Assert.assertEqual(actualResult, expectedResult);
}
}
So one project contains models and logic, then another project contains tests for said library. There is no front end or UI, so I want to do the bare minimum to just be able to test that my methods all work in isolation.

As long as your "library" doesn't contain any references to resources in the Android SDK, there isn't anything more to this than regular unit testing. In your Eclipse workspace, say you have your main project MyAndroidLibProject, you simply create a new Java Project (e.g. MyAndroidLibProjectUnitTests). Inside here, you create ordinary unit tests referring to the Calculator class in your main project (just make sure that your main project is added to the build path of your test project).
You might also find some additional information in a similar question I asked myself earlier, as well as the answer to that question.
Updated with example:
import static org.junit.Assert.*;
import org.junit.Test;
public class SemesterTest
{
#Test
public void aNewSemesterShouldHaveANegativeId()
{
Semester semester = new Semester(2010, SemesterType.FALL);
assertEquals(-1, semester.getInternalId());
}
#Test
public void toStringShouldPrintSemesterTypeAndYear()
{
Semester semester = new Semester(2010, SemesterType.FALL);
assertEquals(SemesterType.FALL + " 2010", semester.toString());
}
#Test
public void equalityShouldOnlyDependOnSemesterTypeAndYear()
{
Semester aSemester = new Semester(2010, SemesterType.FALL);
aSemester.setInternalId(1);
Semester anotherSemester = new Semester(2010, SemesterType.FALL);
anotherSemester.setInternalId(2);
assertEquals(aSemester, anotherSemester);
}
}
The above is a test of my own Semester class (a simple data class representing a semester). Semester is located inside my android project MyMainProject (but the class itself doesn't contain any references to the Android SDK). SemesterTest is located inside my test project MyTestProject (an ordinary Java project), with both MyMainProject and MyTestProject being in the same workspace (and since SemesterTest has the same package name as Semester, I don't need any special import statement to reference Semester either). MyTestProject also has MyMainProject added to its build path (junit.jar is also added to the build path, but this happens automatically, at least in Eclipse I think).
So as you can see, this is nothing but a completely ordinary unit test (JUnit 4, just to have mentioned it). Hope this helps.

Related

How can I call methods from a different java project?

It's as the title says. I'm trying to call methods defined in another Java project. Is there a way I can do that? I tried import statements but that didn't work.
EDIT:
So here is what is sitting in the code now in terms of imports:
enter image description here
and here are some of the functions I want to call that are in the other project:
enter image description here
What I've tried is:
import com.example.cs320EthicsPlayer.api.*
but that doesn't work it just says import can't be resolved.
Where the 2 projects are located:
enter image description here
I'm not too familiar with mvn directories but we are using maven. The methods I want to call are from the cs320EthicsPlayer folder (project) and the file I'm calling it from is from partyinthebackend (another project). I haven't called on the other project at all, and that's what I'm trying to figure out.
Class Path for the file I'm trying to call the functions from:
enter image description here
Let's say we have a class Test inside a package com.example :
package com.example;
public class Test {
public static String getHalloWorld (){
return "Hello world";
}
}
All we need if we want to use our class Test in another package is to use import like that
import com.example.Test;
class OtherPackage {
public static void main(String[] args) {
String geeting = Test.getHalloWorld();
System.out.println(geeting);
}
}
You should remember anything you want to use in another package it should be public.
So just check where is the method, which package and class include the method you are trying to import.
Let's fix your problem now:
try
import com.example*
Now you import the whole package, but you should remember you can import and use just the public method from the package example.
Update:
I see you have updated your question again, and you want to use maven, I think that will answer your question :
Java project dependency on another project
I hope that answers your question.
If it is in the same project but different package you can just doing
import package name...
If it is a complete different project you can't import them. You need to re-insert the methods.

How to add unit tests to Java project in intellij IDEA?

I want to create simple java project with JUnit, so for example I'm want to write an algorithm like merge sort or some Java class and create test class so I can make unit test for that class.
I've create the project with:
File -> New -> Project -> java -> next and setup the project name and
location
and I want to make the unit test for the class the I've created, and I've tried the following solotions :
solution 1 from IntelliJ IDEA dosc using the light bulb to create the test class
solution 2 using shortcut [ctrl + shift + t]
But I always endup with import static org.junit.Assert.*; cannot resolve symbol 'junit', I tried different unit test library end up the same way.
How to resolve this problem so I can make unit test class in this simple Java project?
You can use Gradle or Maven (my personal preference these days).
But the easiest way is to add the JUnit JAR to your project, write some tests, and execute them in IntelliJ.
Go to JUnit and download version 4.12 of the JAR. Put it in a folder /test-lib in your IntelliJ project.
Create a folder /src and add a package /model and a Java class Foo to it (I'll write you one).
Mark /src as a source root.
Create a folder /test and add a package /model and a Java class FooTest to it (I'll write that, too).
Mark /test as a test source root.
Right click on /test and tell IntelliJ to "Run All Tests".
IntelliJ will run all the tests and present the results in the Run window.
Here's the model class:
package model;
public class Foo {
private String value;
public Foo(String v) { this.value = v; }
public String toString() { return this.value; }
}
Here's the test class:
package model;
public class FooTest {
#Test
public void testToString() {
String expected = "Test";
Foo foo = new Foo(expected);
Assert.assertEquals(expected, foo.toString());
}
}
I'm not sure this is the best solutions but I manage to build the unit test use gradle and maven. like this :
create Java project :
File -> New -> Project -> Gradle -> choose only java-> fill the
groupId and ArtifactId-> choose use default gradle wrapper -> enter
project name and location ->finish
and from the root of the project
right click -> Add Framework Support -> choose maven.
from there I can create the class that I want and make the unit test using the solutions from the question [ctrl + shift +t] .

Need help setting up intellij java project with multiple .java files from scratch

Edited to restart question from scratch due to complaints. I am a newbie to this format and to intellij so please excuse...
I am building a project in intellij for class. This project imports jnetcap and uses it to process a captured pcap file. My issue is I have two class files I am trying to integrate. NetTraffic which is the user interface class, and ProcessPacket that actually reads in the packet and does the work.
I have tried to make a project and import ProcessPacket into NetPacket but have been unsuccessful so far. I am sure I am missing something simple in this process but I just can not find anything showing the proper way to do this.
I have gotten it working by making a package under the src directory and adding both files to that package. This doesn't require an import from the NetPacket class and seems to work but my worry is that I need to be able to run this from a linux command line. I have been working all semester so far with everything in one source file so it hasn't been an issue until now. I don't remember using packages in the past under eclipse to do this.
Can someone offer a step by step process on how to properly add these source files to my project so that I am able to import ProcessPacket into NetTraffic or will leaving like this in a package work fine?
The files in question reside in package named nettraffic in src directory.
NetTraffic.java
package nettraffic;
public class NetTraffic {
public static ProcessPacket pp;
public static void main (String args[]) {
pp = new ProcessPacket();
pp.PrintOut();
}
}
ProcessPacket.java
package nettraffic;
import org.jnetpcap.*;
public class ProcessPacket {
public ProcessPacket() {
}
public void PrintOut() {
System.out.println("Test");
}
}
Note there is no real functionality in these at this time. Just trying to get the class import syntax correct before continuing. Again while this seems to work as a package I want to have it done without using a package and importing ProcessPacket.java into NetTraffic.java.
public class NetTraffic {
ProcessPacket pp = new ProcessPacket();
pp.PrintOut();
}
You're calling the PrintOut() method outside of any constructor or method or similar block (static or non-static initializer blocks...), and this isn't legal. Put it in a constructor or method.
public class NetTraffic {
public NetTraffic() {
ProcessPacket pp = new ProcessPacket();
pp.PrintOut();
}
}

Groovy #Immutable classes in Java

I often recommend Groovy's #Immutable AST transformation as an easy way to make classes, well, immutable. This always works fine with other Groovy classes, but someone recently asked me if I could mix those classes into Java code. I always thought the answer was yes, but I'm hitting a snag.
Say I have an immutable User class:
import groovy.transform.Immutable
#Immutable
class User {
int id
String name
}
If I test this using a JUnit test written in Groovy, everything works as expected:
import org.junit.Test
class UserGroovyTest {
#Test
void testMapConstructor() {
assert new User(name: 'name', id: 3)
}
#Test
void testTupleConstructor() {
assert new User(3, 'name')
}
#Test
void testDefaultConstructor() {
assert new User()
}
#Test(expected = ReadOnlyPropertyException)
void testImmutableName() {
User u = new User(id: 3, name: 'name')
u.name = 'other'
}
}
I can do the same with a JUnit test written in Java:
import static org.junit.Assert.*;
import org.junit.Test;
public class UserJavaTest {
#Test
public void testDefaultCtor() {
assertNotNull(new User());
}
#Test
public void testTupleCtor() {
assertNotNull(new User(3, "name"));
}
#Test
public void testImmutableName() {
User u = new User(3, "name");
// u.setName("other") // Method not found; doesn't compile
}
}
This works, though there are troubles on the horizon. IntelliJ 15 doesn't like the call to new User(), claiming that constructor is not found. That also means the IDE underlines the class in red, meaning it has a compilation error. The test passes anyway, which is a bit strange, but so be it.
If I try to use the User class in Java code directly, things start getting weird.
public class UserDemo {
public static void main(String[] args) {
User user = new User();
System.out.println(user);
}
}
Again IntelliJ isn't happy, but compiles and runs. The output is, of all things:
User(0)
That's odd, because although the #Immutable transform does generate a toString method, I rather expected the output to show both properties. Still, that could be because the name property is null, so it's not included in the output.
If I try to use the tuple constructor:
public class UserDemo {
public static void main(String[] args) {
User user = new User(3, "name");
System.out.println(user);
}
}
I get
User(0, name)
as the output, at least this time (sometimes it doesn't work at all).
Then I added a Gradle build file. If I put the Groovy classes under src\main\groovy and the Java classes under src\main\java (same for the tests but using the test folder instead), I immediately get a compilation issue:
> gradle test
error: cannot find symbol
User user = new User(...)
^
I usually fix cross-compilation issues like this by trying to use the Groovy compiler for everything. If I put both classes under src\main\java, nothing changes, which isn't a big surprise. But if I put both classes under src\main\groovy, then I get this during the compileGroovy phase:
> gradle clean test
error: constructor in class User cannot be applied to the given types;
User user = new User(3, "name");
required: no arguments
found: int,String
reason: actual and formal arguments differ in length
Huh. This time it's objecting to the tuple constructor, because it thinks it only has a default constructor. I know the transform adds a default, a map-based, and a tuple constructor, but maybe they're not being generated in time for the Java code to see them.
Incidentally, if I separate the Java and Groovy classes again, and add the following to my Gradle build:
sourceSets {
main {
java { srcDirs = []}
groovy { srcDir 'src/main/java' }
}
}
I get the same error. If I don't add the sourceSets block, I get the User class not found error from earlier.
So the bottom line is, what's the correct way to add an #Immutable Groovy class to an existing Java system? Is there some way to get the constructors to be generated in time for Java to see them?
I've been making Groovy presentations to Java developers for years and saying you can do this, only to now run into problems. Please help me save face somehow. :)
I did try your scenario as well, where you have a single project with a src/main/java and a src/main/groovy directory and ended up with compilation errors similar to what you saw.
I was able to use Groovy immutable objects in Java when I put the Groovy immutables in a separate project from the Java code. I have created a simple example and pushed it to GitHub (https://github.com/cjstehno/immut).
Basically it's a Gradle multi-project with all the Groovy code (the immutable object) in the immut-groovy sub-project and all the Java code in the immut-java project. The immut-java project depends on the immut-groovy project and uses the immutable Something object:
public class SomethingFactory {
Something createSomething(int id, String label){
return new Something(id, label);
}
}
I added a unit test in the Java project which creates a new instance of the immutable Groovy class and verifies its contents.
public class SomethingFactoryTest {
#Test
public void createSomething(){
Something something = new SomethingFactory().createSomething(42, "wonderful");
assertEquals(something.getId(), 42);
assertEquals(something.getLabel(), "wonderful");
}
}
This is not really ideal, but it works.

JUnit testing result of a program

This is a very basic question for JUnit testing. I wrote a program which calculate the new position of a dot by given instructions for moving. The program is working properly but I have to write a JUnit test for check the result and I don't know how.
Write a test method for every dot movement that you want to check. In each test method you call your method and then compare the actual result with the expected result.
Try something like this, using JUnit 4.x :
package org.dotmover;
import org.junit.Assert;
import org.junit.Test;
public class DotMoverTest {
#Test
public void testDotMoverForward() {
final DotMover dotMover = new DotMover(...);
final int newPos = dotMover.move(...);
final int expectedNewPos = ...;
Assert.assertEquals(expectedNewPos, newPos);
}
}
Add JUnit to classpath of you project. The create JUnit testcase. It is just a class that extends TestCase.
If you are using JUnit prior to v 4.0 each test method must start from word test, e.g.
testPosition(), testMoviing() etc.
If you are using version 4 and higher the test methods must be targeted with annotation #Test.
Now write your testing scenario. User static assertXXX() methods of class Assert to verify that your program is working.
Good luck and happy TDD!

Categories