set number of withdraws to 3 and test it in Junit Testing. - java

In a Saving account for the withdraw variables i need to make sure it can't withdraw more than 3 in a month. I checked the criteria in the setter but I'm not sure how to do the testing in the JUintTesting. As both of them are void method and the testing method returns a boolean i am getting a error of void below is my code.
public void setNumberWithdrawals(int w)
{
if (getNumberWithdrawals() > 3)
{
System.out.println("You already have more than 3 withdraw!!");
}
else
{
numberWithdrawals = w;
}
}
For JUNit testing
SavingsAccount sa1;
#Test
public void testsetNumberWithdrawals()
{
assertEquals(true, sa1.setTest(4));
}
I am expecting it to return false since i pass 4 but i keep on getting the void and return type expected error, i even tried assigning the value to another int variable for number and tested it but i still got the error.

Assumption: You're using JUnit 4 (seems like a safe assumption given that the code you provided is using the #Test annotation).
You would want something like this for your test class:
import static org.junit.Assert.*;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class SavingsAccountTest {
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
#Before
public void setUpStreams() {
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));
}
#After
public void cleanUpStreams() {
System.setOut(null);
System.setErr(null);
}
#Test
public void test() {
SavingsAccount savingsAcct = new SavingsAccount(...);
savingsAcct.setNumberWithdrawals(...);
assertEquals("You already have more than 3 withdraw!!\r\n", outContent.toString());
}
}
Other thoughts:
Given the code you posted in your question and code on github some things seem a little strange. It might just be that some of the code is still missing, but I want to point out a few things that stand out:
You posted this code:
assertEquals(true, sa1.setTest(4));
Now according to what I read on github, sa1 is an instance of SavingsAccount yet I don't see a definition for this setTest(...) method anywhere. I do see this SavingsAccount extends Account so I suppose setTest(...) could be defined in the Account class. The reason this stands out is that you said you were trying to test SavingsAccount.setNumberWithdrawals(...) but you're not invoking setNumberWithdrawals in your test. Again, I suppose that this setTest method could indirectly invoke setNumberWithdrawals but that's not clear from everything you posted.
You said in your question:
make sure it can't withdraw more than 3
The logic you have is if (getNumberWithdrawals() > 3) which means the number of withdrawals will have to be more than 3 to trigger this logic. This seems to violate your requirement.

Related

instantiate object from derived class with constructor that takes super argument

Maybe what I am trying to do is not worthwhile, it sure feels that way after spending many days on it.
I have A Base Class shown here:
package jimmy.kilmer.com;
import java.awt.Color;
import jarPackageImports.AI;
import jarPackageImports.MovementAction;
import jarPackageImports.Info;
import jarPackageImports.PlayerAction;
public class GameAI extends AI {
public gameAI(Info info) {
super(info);
setJerseyNumber(32);
}
public Color getColor() {
return Color.RED;
}
public String getName() {
return "Usain Bolt";
}
public PlayerAction update() {
// TODO game movement actions
// all available methods not listed here...
info.getVelocity();
info.getX();
info.getY();
MovementAction steeringBehavior = null;
return steeringBehavior;
}
//basically used for testing setup
public int[][] populateAllPossibleNodes() {
int[][] allPossibleNodes = new int[screenWidth/20][screenHeight/20];
return allPossibleNodes;
}
}
I have been given a jar, that sets up the game environment. It uses reflection for the setup. I am not familiar with reflection, unfortunately, as I am more beginner level.
I have read a lot about TDD, and am convinced that can help me stay orderly, and code in a disciplined way. I have some say that TDD is not really useful for Game development, which the arguments may be true, in regard to making an "enjoyable game." But, from a purely coding standpoint, I remain steadfast in my believe that TDD is the way to go. But, that remains to be seen, since it is still theoretical. I would like to try it.
I have installed Junit 5, and have done many tutorials, but it's all pretty basic examples. My particular test case uses reflection, super classes, derived classes, dynamic data. My head is spinning.
My goal is just to get setup such that I can start doing some Test driven development.
Here is my Junit test class:
package jimmy.kilmer.com;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jarPackageImports.Info;
class GameAITest {
private GameAITest AIObject;
private jarPackageImports.Info info;
#BeforeEach
void setUp() throws Exception {
AIObject = new GameAITest(info);
#AfterEach
void tearDown() throws Exception {
}
#Test
void testPopulateAllPossibleNodes() {
// 1. given/arrange
int[][] array1 = new int[80][65];
// 2. when/act
int[][] array2 = AIObject.populateAllPossibleNodes();
// 3. then/assert
assertArrayEquals(array1, array2);
}
}
That is my best stab so far, but it still get a compile error. Specifically:
java.lang.NullPointerException:Cannot invoke "jarPackageImports.Info.getScene()" because "this.info" is null
In summation:
maybe everything I am trying is rubbish?
Do I need to use dynamic junit testing? I would have to read up on that.
Do I need to mock (use Mockito?) to instantiate an object to test? I would need to read up on that as well.
Is it possible to instantiate an object from GameAI? Do I need to/how would I use relection to do that? class.getConstructors()? And, I would have to read up on that.
thanks in advance.

Check if method was called on EasyMock

Using EasyMock 3.2. In order to unit test an UI, I have to mock some dependencies. One of them is Page. Base class for UI tests looks like this:
abstract class AbstractUiTest {
#Before
public function setUpUiDependencies() {
Page page = createNiceMock(Page.class);
Ui.setCurrentPage(page);
}
}
Most of the time I don't use the page explicity, it's just there not to throw NullPointerException when e.g. Ui calls getPage().setTitle("sth") etc.
However, in a few tests I want to explicity check if something has happend with the page, e.g.:
public class SomeTest extends AbstractUiTest {
#Test
public void testNotification() {
// do something with UI that should cause notification
assertNotificationHasBeenShown();
}
private void assertNotificationHasBeenShown() {
Page page = Ui.getCurrentPage(); // this is my nice mock
// HERE: verify somehow, that page.showNotification() has been called
}
}
How to implement the assertion method? I would really want to implement it without recording behavior to the page, replaying and verifying it. My problem is a bit more complicated, but you should get the point.
EDIT: I think that perhaps this is not really needed, since simply using replay and verify should check that the expected methods were actually called. But you said you want to do this without replaying and verifying. Can you explain why you have that requirement?
I think that you can use andAnswer and an IAnswer. You don't mention what the return value of page.showNotification() is. Assuming it returns a String, you could do this:
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.easymock.IAnswer;
import org.junit.Ignore;
import org.junit.Test;
public class SomeTest extends AbstractUiTest {
#Test
public void shouldCallShowNotification() {
final AtomicBoolean showNotificationCalled = new AtomicBoolean();
expect(page.showNotification()).andAnswer(new IAnswer<String>() {
#Override
public String answer() {
showNotificationCalled.set(true);
return "";
}
});
replay(page);
Ui.getCurrentPage();
verify(page);
assertTrue("showNotification not called", showNotificationCalled.get());
}
}
If showNotification returns void, I believe you would need to do this:
import static org.easymock.EasyMock.expectLastCall;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.easymock.IAnswer;
import org.junit.Ignore;
import org.junit.Test;
public class SomeTest extends AbstractUiTest {
#Test
public void shouldCallShowNotification() {
final AtomicBoolean showNotificationCalled = new AtomicBoolean();
page.showNotification();
expectLastCall().andAnswer(new IAnswer<Void>() {
#Override
public Void answer() {
showNotificationCalled.set(true);
return null;
}
});
replay(page);
Ui.getCurrentPage();
verify(page);
assertTrue("showNotification not called", showNotificationCalled.get());
}
}
Note: I've used an AtomicBoolean to record whether the method was called. You could also use a boolean array of a single element, or your own mutable object. I used AtomicBoolean not for its concurrency properties, but simply because it is a handy mutable boolean object that is already present in the Java standard libraries.
The other thing that I have done to verify that a method was being called is to not use a mock at all, but to create an instance of Page as an anonymous inner class and override the showNotification method, and record somewhere that the call occurred.
Use a nice mock in the tests where you don't care what happens to page and a normal mock in those tests where you want to test something explicit - and use expect, verify etc. I.e. have two variables in your setup method: nicePage (acts as a stub) and mockPage (acts as a mock)

Functional test in java, explanation

This is a sample program:
public class FunctionalTest {
public int f(int r) {
int result = r * 5;
return result;
}
public static void main(String[] args) {
FunctionalTest funct = new FunctionalTest();
System.out.println(funct.f(5));
}
}
I'm a beginner.
How to write a functional test for this code?
How to write functional tests? Do I need to TestNG?
Is it enough to write the examination method?
Could someone explain to me and write a sample functional test for this program?
Well, if you're specifically asking for functional testing, there's not much you can do with that code snippet. You can do a unit test from the f method using JUnit like this:
#Test
public void testF(){
FunctionalTest t1 = new FunctionalTest();
assertEquals((t1.f(1) % 5), 0); //checks that is getting multiplied by 5.
}
However, you want functional testing, so by running your compiled app and assessing the result you're testing your app functionality by multiple units (AKA integration): your f method and your main method.
Regards!
First of all, you need to have a clear definition of contract you want to verify. From the code, I assume it is something like "the method should return the number equal to argument multiplied by 5".
TestNG, JUnit or other test frameworks is not mandatory for your case. The test may look like:
public void testF() {
int arg = 5;
int result = new FunctionalTest().f(arg);
assert result == arg * 5;
}
Also please keep in mind that to use assert you need JVM started with -ea flag.
Beware the terms you used:
the functional testing provide values to your user/customer
That implies:
black box testing: you have to test your whole system (hard+soft)
the test should target your user/customer needs (explicit report or test)
You can use whatever you want to test the feature (from unit test to jbehave).
In your case (using JUnit 4 and AssertJ):
import org.assertj.core.api.Assertions;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
/*
As an user
I want have 25 whatever I sent
*/
public class NumberGenerationTest {
private static final String PATH = "directory of your class file";
private InputStream stdout;
/* Nominal case */
#Test
public void shall_return_number_25_when_called_with_5() throws Exception {
when_I_call_FunctionalTest_with("5");
then_it_returns("25");
}
/* Nominal case or potential error case */
#Test
public void shall_return_number_25_when_called_with_10() throws Exception {
when_I_call_FunctionalTest_with("10");
then_it_returns("25");
}
/* Nominal case or potential error case */
#Test
public void shall_return_number_25_when_called_with_ABC() throws Exception {
when_I_call_FunctionalTest_with("ABC");
then_it_returns("25");
}
private void when_I_call_FunctionalTest_with(String parameter) throws Exception {
ProcessBuilder builder = new ProcessBuilder("java" ,"-classpath", PATH,"FunctionalTest" , parameter);
builder.redirectErrorStream(true);
Process process = builder.start();
stdout = process.getInputStream ();
}
private void then_it_returns(String expectedResult) throws Exception {
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout));
String line = reader.readLine ();
Assertions.assertThat(line).isNotNull();
Assertions.assertThat(line).isEqualTo(expectedResult);
}
}
It seems you have an error in your main() ... or not.

Alternative of mocking a static method present in some jar

I know that if I need to mock a static method, this indicates that my design has some issue, but in my case this does not seem to be a design issue.
BundleContext bundleContext = FrameworkUtil.getBundle(ConfigService.class).getBundleContext();
Here FrameworkUtil is a class present in an api jar. Using it in code cant be a design issue.
my problem here is while running this line
FrameworkUtil.getBundle(ConfigService.class);
returns null So my question, is there any way by which I can replace that null at runtime
I am using Mockito framewrok and my project does not allow me to use powermock.
if I use
doReturn(bundle).when(FrameworkUtil.class)
in this way getBundle method is not visible since its a static method.
You are correct that is not a design issue on your part. Without PowerMock, your options become a bit murkier, though.
I would suggest creating a non-static wrapper for the FrameworkUtil class that you can inject and mock.
Update: (David Wallace)
So you add a new class to your application, something like this
public class UtilWrapper {
public Bundle getBundle(Class<?> theClass) {
return FrameworkUtil.getBundle(theClass);
}
}
This class is so simple that you don't need to unit test it. As a general principle, you should only EVER write unit tests for methods that have some kind of logic to them - branching, looping or exception handling. One-liners should NOT be unit tested.
Now, within your application code, add a field of type UtilWrapper, and a setter for it, to every class that currently calls FrameworkUtil.getBundle. Add this line to the construtor of each such class
utilWrapper = new UtilWrapper();
And replace every call to FrameworkUtil.getBundle with utilWrapper.getBundle.
Now in your test, you make a mock UtilWrapper and stub it to return whatever Bundle you like.
when(mockUtilWrapper.getBundle(ConfigService.class)).thenReturn(someBundleYouMade);
and for the class that you're testing, call setUtilWrapper(mockUtilWrapper) or whatever. You don't need this last step if you're using #InjectMocks.
Now your test should all hang together, but using your mocked UtilWrapper instead of the one that relies on FrameworkUtil.
unit test
package x;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
public class GunTest {
#Before
public void setUp() throws Exception {
}
#Test
public void testFireTrue() {
final Gun unit = Mockito.spy(new Gun());
Mockito.doReturn(5).when(unit).getCount();
assertTrue(unit.fire2());
}
#Test
public void testFireFalse() {
final Gun unit = Mockito.spy(new Gun());
Mockito.doReturn(15).when(unit).getCount();
assertFalse(unit.fire2());
}
}
the unit:
fire calls the static method directly,
fire2 factors out the static call to a protected method:
package x;
public class Gun {
public boolean fire() {
if (StaticClass.getCount() > 10) {
return false;
}
else {
return true;
}
}
public boolean fire2() {
if (getCount() > 10) {
return false;
}
else {
return true;
}
}
protected int getCount() {
return StaticClass.getCount();
}
}

Easy way of running the same junit test over and over?

Like the title says, I'm looking for some simple way to run JUnit 4.x tests several times in a row automatically using Eclipse.
An example would be running the same test 10 times in a row and reporting back the result.
We already have a complex way of doing this but I'm looking for a simple way of doing it so that I can be sorta sure that the flaky test I've been trying to fix stays fixed.
An ideal solution would be an Eclipse plugin/setting/feature that I am unaware of.
The easiest (as in least amount of new code required) way to do this is to run the test as a parametrized test (annotate with an #RunWith(Parameterized.class) and add a method to provide 10 empty parameters). That way the framework will run the test 10 times.
This test would need to be the only test in the class, or better put all test methods should need to be run 10 times in the class.
Here is an example:
#RunWith(Parameterized.class)
public class RunTenTimes {
#Parameterized.Parameters
public static Object[][] data() {
return new Object[10][0];
}
public RunTenTimes() {
}
#Test
public void runsTenTimes() {
System.out.println("run");
}
}
With the above, it is possible to even do it with a parameter-less constructor, but I'm not sure if the framework authors intended that, or if that will break in the future.
If you are implementing your own runner, then you could have the runner run the test 10 times. If you are using a third party runner, then with 4.7, you can use the new #Rule annotation and implement the MethodRule interface so that it takes the statement and executes it 10 times in a for loop. The current disadvantage of this approach is that #Before and #After get run only once. This will likely change in the next version of JUnit (the #Before will run after the #Rule), but regardless you will be acting on the same instance of the object (something that isn't true of the Parameterized runner). This assumes that whatever runner you are running the class with correctly recognizes the #Rule annotations. That is only the case if it is delegating to the JUnit runners.
If you are running with a custom runner that does not recognize the #Rule annotation, then you are really stuck with having to write your own runner that delegates appropriately to that Runner and runs it 10 times.
Note that there are other ways to potentially solve this (such as the Theories runner) but they all require a runner. Unfortunately JUnit does not currently support layers of runners. That is a runner that chains other runners.
With IntelliJ, you can do this from the test configuration. Once you open this window, you can choose to run the test any number of times you want,.
when you run the test, intellij will execute all tests you have selected for the number of times you specified.
Example running 624 tests 10 times:
With JUnit 5 I was able to solve this using the #RepeatedTest annotation:
#RepeatedTest(10)
public void testMyCode() {
//your test code goes here
}
Note that #Test annotation shouldn't be used along with #RepeatedTest.
I've found that Spring's repeat annotation is useful for that kind of thing:
#Repeat(value = 10)
Latest (Spring Framework 4.3.11.RELEASE API) doc:
org.springframework.test.annotation
Unit Testing in Spring
Inspired by the following resources:
blog post
this solution
commented version
Example
Create and use a #Repeat annotation as follows:
public class MyTestClass {
#Rule
public RepeatRule repeatRule = new RepeatRule();
#Test
#Repeat(10)
public void testMyCode() {
//your test code goes here
}
}
Repeat.java
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Retention( RetentionPolicy.RUNTIME )
#Target({ METHOD, ANNOTATION_TYPE })
public #interface Repeat {
int value() default 1;
}
RepeatRule.java
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class RepeatRule implements TestRule {
private static class RepeatStatement extends Statement {
private final Statement statement;
private final int repeat;
public RepeatStatement(Statement statement, int repeat) {
this.statement = statement;
this.repeat = repeat;
}
#Override
public void evaluate() throws Throwable {
for (int i = 0; i < repeat; i++) {
statement.evaluate();
}
}
}
#Override
public Statement apply(Statement statement, Description description) {
Statement result = statement;
Repeat repeat = description.getAnnotation(Repeat.class);
if (repeat != null) {
int times = repeat.value();
result = new RepeatStatement(statement, times);
}
return result;
}
}
PowerMock
Using this solution with #RunWith(PowerMockRunner.class), requires updating to Powermock 1.6.5 (which includes a patch).
Anything wrong with:
#Test
void itWorks() {
// stuff
}
#Test
void itWorksRepeatably() {
for (int i = 0; i < 10; i++) {
itWorks();
}
}
Unlike the case where you are testing each of an array of values, you don't particularly care which run failed.
No need to do in configuration or annotation what you can do in code.
This works much easier for me.
public class RepeatTests extends TestCase {
public static Test suite() {
TestSuite suite = new TestSuite(RepeatTests.class.getName());
for (int i = 0; i < 10; i++) {
suite.addTestSuite(YourTest.class);
}
return suite;
}
}
There's an Intermittent annotation in the tempus-fugit library which works with JUnit 4.7's #Rule to repeat a test several times or with #RunWith.
For example,
#RunWith(IntermittentTestRunner.class)
public class IntermittentTestRunnerTest {
private static int testCounter = 0;
#Test
#Intermittent(repition = 99)
public void annotatedTest() {
testCounter++;
}
}
After the test is run (with the IntermittentTestRunner in the #RunWith), testCounter would be equal to 99.
This is essentially the answer that Yishai provided above, re-written in Kotlin :
#RunWith(Parameterized::class)
class MyTest {
companion object {
private const val numberOfTests = 200
#JvmStatic
#Parameterized.Parameters
fun data(): Array<Array<Any?>> = Array(numberOfTests) { arrayOfNulls<Any?>(0) }
}
#Test
fun testSomething() { }
}
I build a module that allows do this kind of tests. But it is focused not only in repeat. But in guarantee that some piece of code is Thread safe.
https://github.com/anderson-marques/concurrent-testing
Maven dependency:
<dependency>
<groupId>org.lite</groupId>
<artifactId>concurrent-testing</artifactId>
<version>1.0.0</version>
</dependency>
Example of use:
package org.lite.concurrent.testing;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import ConcurrentTest;
import ConcurrentTestsRule;
/**
* Concurrent tests examples
*/
public class ExampleTest {
/**
* Create a new TestRule that will be applied to all tests
*/
#Rule
public ConcurrentTestsRule ct = ConcurrentTestsRule.silentTests();
/**
* Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests.
*/
#Test
#ConcurrentTest(requests = 20, threads = 10)
public void testConcurrentExecutionSuccess(){
Assert.assertTrue(true);
}
/**
* Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests.
*/
#Test
#ConcurrentTest(requests = 200, threads = 10, timeoutMillis = 100)
public void testConcurrentExecutionSuccessWaitOnly100Millissecond(){
}
#Test(expected = RuntimeException.class)
#ConcurrentTest(requests = 3)
public void testConcurrentExecutionFail(){
throw new RuntimeException("Fail");
}
}
This is a open source project. Feel free to improve.
You could run your JUnit test from a main method and repeat it so many times you need:
package tests;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.Result;
public class RepeatedTest {
#Test
public void test() {
fail("Not yet implemented");
}
public static void main(String args[]) {
boolean runForever = true;
while (runForever) {
Result result = org.junit.runner.JUnitCore.runClasses(RepeatedTest.class);
if (result.getFailureCount() > 0) {
runForever = false;
//Do something with the result object
}
}
}
}

Categories