How do I create a JUnit Test for CompareTo? [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am new at programming and I made a compareTo method and I want to create a test to see if it works but I don't know how to.

All in all, you need a basic understanding of JUnit.
Below is is a simple JUnit Test, but please see this blog post for a detailed explanation. Good luck!
#BeforeClass
public static void setUpBeforeClass() throws Exception {
// Run once before any method in this class.
}
#Before
public void setUp() throws Exception {
// Runs once before each method annotated with #Test
}
#Test
public void testSomething() {
// The Sample Test case
fail("Not yet implemented");
}
#Test
public void testAnotherThing() {
// Another Sample Test case
Me me = new Me();
assertEquals("cmd", me.getFirstName());
}
#After
public void tearDown() throws Exception {
// Runs once after each method annotated with #Test.
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
// Run once after all test cases are run
}
}

first create a junit test class (it should be in the option when you right click, it's not "Class")
by default you get a method,
public void test(){
fail("blah blah");
}
test is a method name and it does not matter what it is so feel free to change it as you wish.
fail is a method from org.junit package and you don't want fail there because it will automatically fail whatever you want to test so delete it for now
now I am assuming compareTo method returns negative number or zero or positive number.
so you might want to test whether it returns a value or not first.
(http://junit.sourceforge.net/javadoc/org/junit/Assert.html lists the methods you can use for testing.)
from the list, I see that assertNotNull checks for the return value by your method. if the method correctly works, it will return a value (test succeeds) but if it doesn't, it will throw exception (test fails).
#Test
public void test() {
org.junit.Assert.assertNotNull(yourpackage.yourclass.yourmethod(if static));
}
or
import yourpackage.yourclassname;
#Test
public void test() {
yourclassname test = new yourclassname();
org.junit.Assert.assertNotNull(test.compareTo());
}
but if you have the class with the junit test class in same package, you do not need to do any import.
hope it helps

Related

How to use Mockito properly on Static methods wrapped inside non-static methods?

so I'm trying to use Mockito on a method that has a static method in it. The reason is I cannot use PowerMock so I wrapped the method under non-static method.
public class WrapperUtil {
public String getURLContent(String path) throws IOException{
URL url = new URL(path);
return IOUtils.toString(url);
}
}
Now I tested the WrapperUtil class in two different ways. One test worked, but did not provide any coverage for WrapperUtil class, the other is throwing a null pointer exception related to the static method.
This is the one that works, but did not provide any coverage.
#RunWith(MockitoJUnitRunner.class)
public class WrapperUtilTest {
#InjectMocks
WrapperUtil ioutils;
#Before
public void setUp() throws Exception {
ioutils = new WrapperUtil();
}
#Test
public void testGetUrlContent() throws IOException {
WrapperUtil ioutilsSpy = Mockito.spy(ioutils);
Mockito.doReturn("test").when(ioutilsSpy).getURLContent(Mockito.anyString());
assertTrue(ioutils2.getURLContent("test").contains("test"));
}
}
This is the one that does not work:
#RunWith(MockitoJUnitRunner.class)
public class WrapperUtilTest {
#InjectMocks
WrapperUtil ioutils;
#Before
public void setUp() throws Exception {
ioutils = new WrapperUtil();
}
#Test
public void testGetUrlContent() throws IOException {
WrapperUtil ioutilsSpy = Mockito.spy(ioutils);
Mockito.when(ioutilsSpy).getURLContent(Mockito.anyString()).thenReturn("test");
assertTrue(ioutils2.getURLContent("test").contains("test"));
}
}
How can I make this work, and achieve code coverage without using PowerMockito? Thank you so much for your help.
My two cent here:
I would even go one step further and define an interface to denote the functionality
On the other hand, I would not go "overboard" testing the wrapper implementation
Point is: there is just a tiny bit of glue code here. If you are able to test this code to verify that this glue code works - then you are fine.
In other words: avoid getting hung up on achieving 100% coverage! Coverage is a tool, designed to help you achieving code quality.
100% coverage does not lead to "100% code quality"!
You achieve code quality by trying to "do the right thing all the time".
Here, the "right thing" is not to strive for 100% coverage.
As I guess that you will not achieve that goal without turning to PowerMock(ito). And as avoiding PowerMock(ito) is by itself a good thing - my suggestion is: simply accept that you can't get to 100% coverage for this class.
If at all, I would spend my time trying to exclude this class from coverage runs.

How to assert that void method throws Exception using Mockito and catch-exception?

I'm trying to test this method:
public void deleteCurrentlyLoggedInUser(Principal principal) {
if (findLoggedInUser(principal) == null) {
throw new UserAlreadyDeletedException();
}
userRepository.delete(findLoggedInUser(principal));
}
Here is findLoggedInUser:
User findLoggedInUser(Principal principal) {
return userRepository.findByUsername(principal.getName());
}
And here is my test so far:
#Test
public void shouldThrowExceptionWhenUserNotFound() {
// given
when(sut.findLoggedInUser(principalStub)).thenReturn(null);
// when
sut.deleteCurrentlyLoggedInUser(principalStub);
// then
catchException
verify(userRepositoryMock, never()).delete(any(User.class));
}
So how do I catch exception using catch-exception here? Method that I'm testing returns void and I just can't seem to find a way to assert that exception was found.
EDIT: I know I could use: #Test(expected = UserAlreadyDeletedException.class) but I want to switch my whole project to catch-exception because it's much better and using expected in #Test is not very reasonable.
I've never heard of catch-exception, but it doesn't exactly seem like an up-to-date library: the last update to the main source code (at the time of writing) was on May 3 2015.
If you're using Java 8, and can use JUnit 4.13 or later, you can use assertThrows:
assertThrows(
UserAlreadyDeletedException.class,
() -> sut.deleteCurrentlyLoggedInUser(principalStub));
If you're going to migrate all of your code to something, this seems like a better long-term bet.
It might be that using Rules is something that could work for you?
Rules allow very flexible addition or redefinition of the behavior of each test method in a test class. Testers can reuse or extend one of the provided Rules below, or write their own.
You can read more about this neat feature of junit4 here:
https://github.com/junit-team/junit4/wiki/Rules
Example:
public static class HasExpectedException {
#Rule
public final ExpectedException thrown = ExpectedException.none();
#Test
public void throwsNullPointerException() {
thrown.expect(NullPointerException.class);
throw new NullPointerException();
}
}

testNG annotation which would equal to "finally" in java?

i don't know if my question was clear, but i am using testNG and i have this:
#Test
public void passengerServiceTest() {
...
}
#AfterTest
public void deleteCreatedPassenger() {
...
}
I want to execute my deleteCreatedPassenger() method after passengerServiceTest, also, i want that in case of deleteCreatedPassenger fails, passengerServiceTest fails too, in other words, i want that both of them be the same test, so if one them fails, test fails.
So i tried with the annotations #AfterTest, #AfterMethod, #AfterClass and all make two tests as "separated" tests.
Do you know how to do this? Regards
You don't need annotations to achieve this, since it's exactly what the finally block is intended for:
#Test
public void passengerServiceTest() {
try {
//test code
} finally {
deleteCreatedPassenger();
}
}
public void deleteCreatedPassenger() {
...
}
If the delete throws an exception then your service test fails.
Annotations are useful in certain scenarios, you shouldn't aim to use them over core language constructs.
alwaysRun
https://testng.org/doc/documentation-main.html
Ex:
#AfterTest(alwaysRun = true)
public void deleteOldValuesFromDatabase() {
...
}
Docs say that this will cause the method to run "even if one or more methods invoked previously failed or was skipped"

How to run specific junit tests at run time

I'm trying to figure out a good solution to having specific unit tests run with certain runtime configurations. For example:
public class TestClassAlpha() {
#setup
public void setup() {
}
#After
public void tearDown() {
}
#Test
#<only run in particular env>
public void testA() {
//whatever A
}
//always run below test no mater what env
#Test
public void testB() {
//whatever B
}
}
I am contemplating a custom annotation or custom rule perhaps, but i thought this has to be a question that comes up frequently as running tests in certain conditions (envs) is a very valid scenario. I did some limited searching within stack, and I didn't find anything that really that helped solidify either way.
This post shows you exactly what you require.
You should Write a Custom TestRule and an annotation to mark the condition.

Conditionally ignoring tests in JUnit 4

OK, so the #Ignore annotation is good for marking that a test case shouldn't be run.
However, sometimes I want to ignore a test based on runtime information. An example might be if I have a concurrency test that needs to be run on a machine with a certain number of cores. If this test were run on a uniprocessor machine, I don't think it would be correct to just pass the test (since it hasn't been run), and it certainly wouldn't be right to fail the test and break the build.
So I want to be able to ignore tests at runtime, as this seems like the right outcome (since the test framework will allow the build to pass but record that the tests weren't run). I'm fairly sure that the annotation won't give me this flexibility, and suspect that I'll need to manually create the test suite for the class in question. However, the documentation doesn't mention anything about this and looking through the API it's also not clear how this would be done programmatically (i.e. how do I programatically create an instance of Test or similar that is equivalent to that created by the #Ignore annotation?).
If anyone has done something similar in the past, or has a bright idea of how else I could go about this, I'd be happy to hear about it.
The JUnit way is to do this at run-time is org.junit.Assume.
#Before
public void beforeMethod() {
org.junit.Assume.assumeTrue(someCondition());
// rest of setup.
}
You can do it in a #Before method or in the test itself, but not in an #After method. If you do it in the test itself, your #Before method will get run. You can also do it within #BeforeClass to prevent class initialization.
An assumption failure causes the test to be ignored.
Edit: To compare with the #RunIf annotation from junit-ext, their sample code would look like this:
#Test
public void calculateTotalSalary() {
assumeThat(Database.connect(), is(notNull()));
//test code below.
}
Not to mention that it is much easier to capture and use the connection from the Database.connect() method this way.
You should checkout Junit-ext project. They have RunIf annotation that performs conditional tests, like:
#Test
#RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
//your code there
}
class DatabaseIsConnected implements Checker {
public boolean satisify() {
return Database.connect() != null;
}
}
[Code sample taken from their tutorial]
In JUnit 4, another option for you may be to create an annotation to denote that the test needs to meet your custom criteria, then extend the default runner with your own and using reflection, base your decision on the custom criteria. It may look something like this:
public class CustomRunner extends BlockJUnit4ClassRunner {
public CTRunner(Class<?> klass) throws initializationError {
super(klass);
}
#Override
protected boolean isIgnored(FrameworkMethod child) {
if(shouldIgnore()) {
return true;
}
return super.isIgnored(child);
}
private boolean shouldIgnore(class) {
/* some custom criteria */
}
}
Additionally to the answer of #tkruse and #Yishai:
I do this way to conditionally skip test methods especially for Parameterized tests, if a test method should only run for some test data records.
public class MyTest {
// get current test method
#Rule public TestName testName = new TestName();
#Before
public void setUp() {
org.junit.Assume.assumeTrue(new Function<String, Boolean>() {
#Override
public Boolean apply(String testMethod) {
if (testMethod.startsWith("testMyMethod")) {
return <some condition>;
}
return true;
}
}.apply(testName.getMethodName()));
... continue setup ...
}
}
A quick note: Assume.assumeTrue(condition) ignores rest of the steps but passes the test.
To fail the test, use org.junit.Assert.fail() inside the conditional statement. Works same like Assume.assumeTrue() but fails the test.

Categories

Resources