how to initialize common resource names in multiple junit4 test classes - java

I am creating a set of junit test classes ,all of which read from the same input data files.I created a test suite as below,but found that I would be replicating the filenames in each test class.
So, how do I do this without repeating the code..
#RunWith(Suite.class)
#SuiteClasses({SomeTests.class,someOtherTests.class})
public class AllTests{
}
-------------------
public class SomeTests{
private String[] allfiles;
public SomeTests() {
allfiles = new String[] {"data1.txt","data2.txt"};
}
#Test
public void testXX1(){
//
}
#Test
public void testXX2(){
//
}
}
public class someOtherTests{
private String[] allfiles;
public someOtherTests() {
allfiles = new String[] {"data1.txt","data2.txt"};
}
#Test
public void testYY(){
//
}
}
I thought I would have to make another class to provide the filenames as a String array..sothat the test classes can initialize the allfiles variable by calling the getFileNames() static method,combining this this with BeforeClass annotation
public class FileNames {
public static String[] getFileNames() {
return new String[]{"data1.txt","data2.txt"};
}
}
public class SomeTests{
private String[] allfiles;
public SomeTests() {
}
#BeforeClass
public void setUp(){
allfiles = FileNames.getFileNames();
}
#Test
public void testXX1(){
//
}
#Test
public void testXX2(){
//
}
}
but I am not sure that is the right way. This will require setUp() to be declared as static ,and that means I will have to make the instance variable allfiles static !
I think this is a common scenario in junit testing ..so can someone please tell me how to do this properly?

Use #Before instead of #BeforeClass, then your setUp() method need not be static.
However, unless you are going to modify your filename array in your tests, you could also create a base class for your tests and declare a protected constant with those names:
public class FileBasedTests {
protected static final String[] FILENAMES = {"data1.txt","data2.txt"}
}
public class SomeTests extends FileBasedTests {
...
}
If you really are concerned about each test having its own copy of those file names, you can write allFiles = FILENAMES.clone().

Related

Static Variable test switching enviroment Java

Hi there I wanna test this class in java, but I have problems because only can call the object inside of assertEquals, if I declare this before will avoid the interception de "when" with the method isProduction, how i can clean this class for each test that I will want execute:
public class SalesforceConstants {
public static final String SALESFORCE_APPROVAL =
RuntimeEnvironment.get().isProduction()
? "salesforss#ssd.com"
: "approver#meretest.com";
public static final String SALESFORCE_REQUESTER = "requester.local#meradda.com"; }
public void test(){
try (MockedStatic<RuntimeEnvironment> routingHelperMockedStatic = mockStatic(RuntimeEnvironment.class)) {
RuntimeEnvironment runtime = mock(RuntimeEnvironment.class);
when(runtime.isProduction()).thenReturn(true);
routingHelperMockedStatic.when(RuntimeEnvironment::get).thenReturn(runtime);
}
assertEquals(SalesforceConstants.SALESFORCE_APPROVAL, "salesforss#ssd.com");
}

JMockit verify if private method is called

I am testig a public method and I want to verify if a private method, that have mocked params, is called.
All the answers I have found are using invoke method, but this was removed since JMockit v1.36
public class ClassToTest{
public void methodToTest(){
DependencyClass abc = new DependencyClass();
if(privateMethod1()){
privateMethod2(abc);
}
}
private boolean privateMethod1(){ return true; }
private void privateMethod2(DependencyClass abc){ abc.doStuff(); }
}
public class testClassToTest{
#Mocked
DependencyClass abc;
#Tested
ClassToTest testedClass;
#BeforeEach
public void setUp() {
testedClass = new ClassToTest();
}
#Test
public void testMethod(){
new MockUp<ClassToTest>() {
#Mock
private boolean privateMethod1() {
return true;
}
};
testedClass.methodToTest();
new FullVerificationsInOrder() {{
abc = new DependencyClass();
//Check here if privateMethod2(abc) gets called once
}};
}
You can use Powermock to mock and verify private methods.
Please check https://github.com/powermock/powermock/wiki/MockPrivate
You have two ways:
To level up your method's scope from private to package-private and after it, your method will become visible in the test.
Refactoring your code and encapsulate the private method to Predicate and after it, you can test your primary method and Predicate separately.
You can't test the private method by Junit.

Mocking a DAO in Mockito

I'm just getting into testing of code. I have done unit tests before but haven't really isolated them. So they were more like integration test (indirectly). I want to give Mockito a try and I have added it to my Intellij IDE.
But I have no idea of how to actually implement mocking at all. There are examples on their website but I just can't wrap my head around the concept of mocking. I know that one uses mocking to isolate the unit testing to ensure that the errors are in the unit itself and not in a dependency.
I wrote the following:
#Test
public void testChangeMemberReturnsTrue() throws Exception {
Member tempMem = new Member();
tempMem.setMemberFirstName("Swagrid");
tempMem.setMemberLastName("McLovin");
tempMem.setMemberID("SM666");
SQLDUMMY.saveMember(tempMem); //Save member to dummy DB.
Member checkMem = new Member();
ArrayList<Member> memArr = SQLDUMMY.getAllMembers();
for (Member m : memArr) { // Look through all saved members
if (m.equals(tempMem)) { // If match, save to checkMem
checkMem = m;
}
}
assertTrue(tempMem.equals(checkMem)); // Make sure they are really equal.
String newfirstname = "Darius";
String newlastname = "DunkMaster";
assertTrue(memhandling.changeMember(tempMem, newfirstname, newlastname));
}
And here is the actual method:
public boolean changeMember(Member mem, String n1, String n2) {
try {
ArrayList<Member> memArr = SQLDUMMY.getAllMembers();
for (Member m : memArr) {
if (m.equals(mem)) {
m.setMemberFirstName(n1);
m.setMemberLastName(n2);
m.setMemberID(ensureUniqueID(m, m.getMemberID())); //Just a method call to another method in the same class to ensure ID uniqueness.
return true;
}
else {
return false;
}
}
}
catch (Exception e) {
System.out.println("Error4.");
}
return false;
}
I'd like to mock the SQLDUMMY (Which I created just to see if my tests would pass at all, which they do.) The SQLDUMMY class looks like this:
public class SQLDUMMY {
private static ArrayList<Member> memberList = new ArrayList<>();
private static ArrayList<Ship> shipList = new ArrayList<>();
public static ArrayList<Member> getAllMembers() {
return memberList;
}
public static void saveMember(Member m) {
memberList.add(m);
}
public static void deleteMember(Member memIn) {
memberList.remove(memIn);
}
public static void saveShip(Ship newShip) {
shipList.add(newShip);
}
public static ArrayList<Ship> getAllShips() {
return shipList;
}
public static void deleteShip(Ship s) {
shipList.remove(s);
}
}
It basically just consists of getters and add/remove for the ArrayLists that act as a contemporary DB storage.
Summary: How can I mock the SQLDUMMY class (DAO), so it is no longer a dependency for the Unit tests?
You need to read on how Mockito works.
The basic idea is that it extends you class and and overrides all methods and allows you to return what ever you want it too.
Syntax is :
SQLDummy sqlDummy = Mockito.mock(SQLDummy.class);
Mockito.when(sqlDummy.getAllShips()).thenReturn(new ArrayList< Ship >())

Running Android Tests setUp() method gets called multiple times

I am creating a test suite for my android application and have this setUp method
private static final String TAG_NAME = "TESTING_SUITE";
public TestingMusicDAO musicDAO;
public List<Song> songs;
public Instrumentation instr;
MusicService musicService;
#Override
public void setUp() throws Exception {
instr = this.getInstrumentation();
Log.d(TAG_NAME, "Setting up testing songs");
musicDAO = new TestingMusicDAO(instr.getContext());
musicService = new MusicServiceImpl(musicDAO);
musicDAO.getAllSongsFromFile();
songs = musicDAO.getAllSongs();
for(Song song : songs)
Log.d( TAG_NAME, song.toString() );
}
And then have these tests which are created by a python tool from a text file
public void test1() {
List<Song> testPlaylist;
String testArtist = ("The Beatles");
String actualArtist = ("TheBeatles");
testPlaylist = testingPlaySongsByKeyword(testArtist);
if(testPlaylist.isEmpty()){
fail("No Songs Were Found");
} else {
for( Song loopsongs : testPlaylist){
if (!(loopsongs.getArtist().equals(actualArtist))){
fail("Song Doesnt Contain the artist" + actualArtist + "... Contains ->" + loopsongs.getArtist());
}
}
}
}
and every time one of these gets called the musicDAO is regenerated. How can I stop the setup method from being called
You don't. The design of JUnit is that setUp() and tearDown() are done once per test. If you want it done per class, do it in the constructor. Just make sure that you don't alter anything inside the classes. The reason for doing it once per test is to make sure all tests start with the same data.
You could use #BeforeClass and #AfterClass annotations from JUnit.
#BeforeClass
public static void test_setUp_Once(){
// Code which you want to be executed only once
createDb();
}
#AfterClass
public static void test_tearDown_Once(){
// Code which you want to be executed only once
deleteDb();
}
Note: You need to declare these methods static to work properly.
I had the same basic problem. I want to be able to test the structure of my database, so I create it in the setUp method and delete it in the tearDown. Using the constructor wouldn't solve my need to delete the database once all my tests are executed, so I used some reentrant logic:
static int testsExecutedSoFar = 0;
static boolean isFirstRun = true;
#Override
protected void setUp() throws Exception {
if(isFirstRun){
createDb();
isFirstRun = false;
}
}
#Override
protected void tearDown() throws Exception{
testsExecutedSoFar++;
if (testsExecutedSoFar == totalNumberOfTestCases())
deleteDb();
}
private int totalNumberOfTestCases() {
return countTestCases()+1; //have to add one for testandroidtestcasesetupproperly added by AndroidTestCase
}
The fields have to be static since JUnit creates a new instance of the class for each run. The magic 1 had to be added since AndroidTestCase adds it's own test (testandroidtestcasesetupproperly) to the test suite but it doesn't count towards the number returned by countTestCases().
A bit on the ugly side, but it did the trick.

Get name of currently executing test in JUnit 4

In JUnit 3, I could get the name of the currently running test like this:
public class MyTest extends TestCase
{
public void testSomething()
{
System.out.println("Current test is " + getName());
...
}
}
which would print "Current test is testSomething".
Is there any out-of-the-box or simple way to do this in JUnit 4?
Background: Obviously, I don't want to just print the name of the test. I want to load test-specific data that is stored in a resource with the same name as the test. You know, convention over configuration and all that.
JUnit 4.7 added this feature it seems using TestName-Rule. Looks like this will get you the method name:
import org.junit.Rule;
public class NameRuleTest {
#Rule public TestName name = new TestName();
#Test public void testA() {
assertEquals("testA", name.getMethodName());
}
#Test public void testB() {
assertEquals("testB", name.getMethodName());
}
}
JUnit 4.9.x and higher
Since JUnit 4.9, the TestWatchman class has been deprecated in favour of the TestWatcher class, which has invocation:
#Rule
public TestRule watcher = new TestWatcher() {
protected void starting(Description description) {
System.out.println("Starting test: " + description.getMethodName());
}
};
Note: The containing class must be declared public.
JUnit 4.7.x - 4.8.x
The following approach will print method names for all tests in a class:
#Rule
public MethodRule watchman = new TestWatchman() {
public void starting(FrameworkMethod method) {
System.out.println("Starting test: " + method.getName());
}
};
JUnit 5 and higher
In JUnit 5 you can inject TestInfo which simplifies test metadata injection to test methods. For example:
#Test
#DisplayName("This is my test")
#Tag("It is my tag")
void test1(TestInfo testInfo) {
assertEquals("This is my test", testInfo.getDisplayName());
assertTrue(testInfo.getTags().contains("It is my tag"));
}
See more: JUnit 5 User guide, TestInfo javadoc.
Try this instead:
public class MyTest {
#Rule
public TestName testName = new TestName();
#Rule
public TestWatcher testWatcher = new TestWatcher() {
#Override
protected void starting(final Description description) {
String methodName = description.getMethodName();
String className = description.getClassName();
className = className.substring(className.lastIndexOf('.') + 1);
System.err.println("Starting JUnit-test: " + className + " " + methodName);
}
};
#Test
public void testA() {
assertEquals("testA", testName.getMethodName());
}
#Test
public void testB() {
assertEquals("testB", testName.getMethodName());
}
}
The output looks like this:
Starting JUnit-test: MyTest testA
Starting JUnit-test: MyTest testB
NOTE: This DOES NOT work if your test is a subclass of TestCase! The test runs but the #Rule code just never runs.
Consider using SLF4J (Simple Logging Facade for Java) provides some neat improvements using parameterized messages. Combining SLF4J with JUnit 4 rule implementations can provide more efficient test class logging techniques.
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.rules.TestWatchman;
import org.junit.runners.model.FrameworkMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggingTest {
#Rule public MethodRule watchman = new TestWatchman() {
public void starting(FrameworkMethod method) {
logger.info("{} being run...", method.getName());
}
};
final Logger logger =
LoggerFactory.getLogger(LoggingTest.class);
#Test
public void testA() {
}
#Test
public void testB() {
}
}
A convoluted way is to create your own Runner by subclassing org.junit.runners.BlockJUnit4ClassRunner.
You can then do something like this:
public class NameAwareRunner extends BlockJUnit4ClassRunner {
public NameAwareRunner(Class<?> aClass) throws InitializationError {
super(aClass);
}
#Override
protected Statement methodBlock(FrameworkMethod frameworkMethod) {
System.err.println(frameworkMethod.getName());
return super.methodBlock(frameworkMethod);
}
}
Then for each test class, you'll need to add a #RunWith(NameAwareRunner.class) annotation. Alternatively, you could put that annotation on a Test superclass if you don't want to remember it every time. This, of course, limits your selection of runners but that may be acceptable.
Also, it may take a little bit of kung fu to get the current test name out of the Runner and into your framework, but this at least gets you the name.
JUnit 4 does not have any out-of-the-box mechanism for a test case to get it’s own name (including during setup and teardown).
String testName = null;
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (int i = trace.length - 1; i > 0; --i) {
StackTraceElement ste = trace[i];
try {
Class<?> cls = Class.forName(ste.getClassName());
Method method = cls.getDeclaredMethod(ste.getMethodName());
Test annotation = method.getAnnotation(Test.class);
if (annotation != null) {
testName = ste.getClassName() + "." + ste.getMethodName();
break;
}
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
}
Based on the previous comment and further considering I created an extension of TestWather which you can use in your JUnit test methods with this:
public class ImportUtilsTest {
private static final Logger LOGGER = Logger.getLogger(ImportUtilsTest.class);
#Rule
public TestWatcher testWatcher = new JUnitHelper(LOGGER);
#Test
public test1(){
...
}
}
The test helper class is the next:
public class JUnitHelper extends TestWatcher {
private Logger LOGGER;
public JUnitHelper(Logger LOGGER) {
this.LOGGER = LOGGER;
}
#Override
protected void starting(final Description description) {
LOGGER.info("STARTED " + description.getMethodName());
}
#Override
protected void succeeded(Description description) {
LOGGER.info("SUCCESSFUL " + description.getMethodName());
}
#Override
protected void failed(Throwable e, Description description) {
LOGGER.error("FAILURE " + description.getMethodName());
}
}
Enjoy!
In JUnit 5 TestInfo acts as a drop-in replacement for the TestName rule from JUnit 4.
From the documentation :
TestInfo is used to inject information about the current test or
container into to #Test, #RepeatedTest, #ParameterizedTest,
#TestFactory, #BeforeEach, #AfterEach, #BeforeAll, and #AfterAll
methods.
To retrieve the method name of the current executed test, you have two options : String TestInfo.getDisplayName() and
Method TestInfo.getTestMethod().
To retrieve only the name of the current test method TestInfo.getDisplayName() may not be enough as the test method default display name is methodName(TypeArg1, TypeArg2, ... TypeArg3).
Duplicating method names in #DisplayName("..") is not necessary a good idea.
As alternative you could use
TestInfo.getTestMethod() that returns a Optional<Method> object.
If the retrieval method is used inside a test method, you don't even need to test the Optional wrapped value.
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.Test;
#Test
void doThat(TestInfo testInfo) throws Exception {
Assertions.assertEquals("doThat(TestInfo)",testInfo.getDisplayName());
Assertions.assertEquals("doThat",testInfo.getTestMethod().get().getName());
}
JUnit 5 via ExtensionContext
Advantage:
You get to have the added functionalities of ExtensionContext by overriding afterEach(ExtensionContext context).
public abstract class BaseTest {
protected WebDriver driver;
#RegisterExtension
AfterEachExtension afterEachExtension = new AfterEachExtension();
#BeforeEach
public void beforeEach() {
// Initialise driver
}
#AfterEach
public void afterEach() {
afterEachExtension.setDriver(driver);
}
}
public class AfterEachExtension implements AfterEachCallback {
private WebDriver driver;
public void setDriver(WebDriver driver) {
this.driver = driver;
}
#Override
public void afterEach(ExtensionContext context) {
String testMethodName = context.getTestMethod().orElseThrow().getName();
// Attach test steps, attach scsreenshots on failure only, etc.
driver.quit();
}
}
#ClassRule
public static TestRule watchman = new TestWatcher() {
#Override
protected void starting( final Description description ) {
String mN = description.getMethodName();
if ( mN == null ) {
mN = "setUpBeforeClass..";
}
final String s = StringTools.toString( "starting..JUnit-Test: %s.%s", description.getClassName(), mN );
System.err.println( s );
}
};
I usually use something like this:
/** Returns text with test method name
#param offset index of method on call stack to print, 1 for a caller of this method.
*/
static String getName(int offset)
{
Throwable t = new Throwable();
t.fillInStackTrace();
return
t.getStackTrace()[offset].getMethodName()+":"+t.getStackTrace()[offset].getLineNumber();
};
This is exactly what Exception do use when printing stack trace.
Depending on the exact context You may have to figure out correct offset value. It is crude and primitive tough and is not using any fancy modern futures.
I'd suggest you decouple the test method name from your test data set. I would model a DataLoaderFactory class which loads/caches the sets of test data from your resources, and then in your test case cam call some interface method which returns a set of test data for the test case. Having the test data tied to the test method name assumes the test data can only be used once, where in most case i'd suggest that the same test data in uses in multiple tests to verify various aspects of your business logic.
You can achieve this using Slf4j and TestWatcher
private static Logger _log = LoggerFactory.getLogger(SampleTest.class.getName());
#Rule
public TestWatcher watchman = new TestWatcher() {
#Override
public void starting(final Description method) {
_log.info("being run..." + method.getMethodName());
}
};
I have a Junit4 test class that extends TestCase so the example with #Rule didn't work (as mentioned in other answers).
However, if your class extends TestCase you can use getName() to get the current test name so this works:
#Before
public void setUp() {
System.out.println("Start test: " + getName());
}
#After
public void tearDown() {
System.out.println("Finish test: " + getName());
}
A more simpler way is to put this logic in setUp() and tearDown() methods.
Refer below code for better clarity,
import java.lang.reflect.Method;
#BeforeMethod
void setUp(Method method) {
log.info("###############################################");
log.info("Running Test: {}", method.getName());
}
#AfterMethod
void tearDown(Method method) {
log.info("Finished Test: {}", method.getName());
log.info("###############################################");
}
#Test
public void testMethodName() {
// Method logic implementation...
}
Here is the output of above test execution,
#############################################################
Running Test: testMethodName
// Logs related to method execution...
Finished Test: testMethodName
#############################################################

Categories

Resources