How to use OR condition with TestNG assertions - java

Is there a way to do assertions with OR with TestNG?
This is what I am trying to find:
assertEquals(expected, value1 || value2); // Can be any number of values.

You could make a very simple wrapper around the TestNG code:
private void assertContains(Object actual, Object ... expected) {
assertTrue(Arrays.asList(expected).contains(actual));
}
I briefly looked through the TestNG source code and didn't see any methods similar to the method above, but I am not very familiar with the TestNG patterns.

I just did a workaround with boolean assertions:
if(condition1 || condition2){
Assert.assertTrue(true)
} else {
Assert.fail("Your Explanation here")
}

Related

Why JUnit test methods need to be void?

I've read in lot of places that test methods should/must be void, but no one says what is the reason for this.
I found in MethodValidator the following check without comments/javadocs.
if (each.getReturnType() != Void.TYPE) {
errors.add(new Exception("Method " + each.getName()
+ " should be void"));
}
So why it should be void?
Ask you the reverse question : why JUnit test methods would need to be not void ?
No reason : because a test method is not designed to return a result that will be exploited by a client class.
The goal of an unit test is validating some assertions. A test runner invokes the test methods and and this is the runner that interprets any assertion failure or any exception thrown during the test execution to produce the test result.
We could wonder why tests don't return the assertion result.
But it would be a bad idea as it would be very cumbersome to write unit tests :
#Test
public AssertionResult foo(){
Bar actualBar = foo.doThat(...);
if (actualBar == null){
return AssertionResult.fail("actualBar == null");
}
}
Write something like that is really readable and straight :
#Test
public void foo(){
Bar actualBar = foo.doThat(...);
Assert.assertNotNull(actualBar);
}
We could also wonder why test methods cannot be invoked by other test methods such as :
#Test
public int foo(){
Bar actualBar = foo.doThat(...);
//...
return intValue;
}
#Test
public void fooWithComputedInt(){
Bar actualBar = foo.doThat(foo());
//...
}
But this also would be not a good idea as this would couple the tests execution while unit tests execution has to be isolated from others. And it also would make the tests be executed multiple times and unit tests have to be executed as fast as possible.
So really no value to make a test method return other thing than void.
This is purely a design choice. JUnit does not know about your code, so it could not do anything if your method would return something.
So either it should discard a return value, or require you to use "void" methods. The authors chose the latter option - you could argue that this slightly better because it's not confusing the reader.
Note that non-#Test methods are free to do whatever they want - they don't have this limitation.

How to check whether Junit is running with JunitRunner or PowermockRunner

During writing junits to the classes, I got some requirement like executing tests in with different runners like once with JUnitRunner and then with PowermockRunner, so based on that I want to decide whether to skip test or continue. Please could you let me know is there any way to check like this?
Thanks in advance.
There are several options, but none of them is pretty.
Your best bet would be if either of these runners supported a system property that you can query, but I doubt that.
Failing that, you can either do a class lookup or inspect the stack.
Class Lookup
boolean isPowerMock = false;
try{
Class.forName("fully.qualified.name.of.PowerMockRunner");
isPowerMock = true;
}catch(ClassNotFoundException e){}
Note that this technique may return a false positive if PowerMock is on the class path, but the runner isn't used.
Inspect stack
boolean isPowerMockRunner = false;
for (StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
if(stackTraceElement.getClassName().contains("PowerMockRunner")) {
isPowerMockRunner = true;
break;
}
}
Or, Java 8-style:
boolean isPowerMock = Arrays.stream(
Thread.currentThread()
.getStackTrace()
)
.anyMatch(
elem -> elem.getClassName()
.contains("PowerMockRunner")
);

Custom hamcrest matcher that works with "not"?

I have some class (say, Entity).
I want to be able to
test that an instance of that is "valid", using some custom code to decide that
also test that an instance is not valid, ideally using the same code.
Using maven, surefire, JUnit 4.11 (and the hamcrest stuff shipped with it).
So I write a class something like this
class IsValidEntity extends TypeSafeMatcher<Entity>{
#Override public boolean matchesSafely(Entity e){
// and here I do a bunch of asserts...
assertNotNull(e.id);
// etc.
}
#Override
public void describeTo(Description description) {
description.appendText("is valid entity");
}
#Factory
public static <T> Matcher<Entity> validEntity() {
return new IsValidEntity();
}
}
OK, fine, I can then do
assertThat(entity, is(validEntity());
in a JUnit test, peachy.
But I can't do
assertThat(entity, not(validEntity());
because the validEntity fails with broken asserts, while for not I guess it should just return false.
Clearly I'm doing something backwards here but I'm not sure what's the most clever way of doing these custom matchers. Or maybe I shouldn't be using TypeSafeMatcher at all but doing something different?
Your matchesSafely method should be rewritten to avoid throwing assertion failures. Instead, just perform the checks manually and then return false if necessary.
Then, you can negate it in the manner you desire without consequence.
You should not be using assert methods in the matchesSafely. You should only be doing boolean logic to return either true or false. It is the responsibility of the calling code to throw the assert error and / or wrap in the not. Therefore you should be doing something like this:
public boolean matchesSafely(...){
boolean result = true;
result &= value1 == value2;
result &= entity.getVal2() == someOtherVal2;
return result;
}
While the other answers are more correct, another approach might be to catch your exceptions within the matcher and then return false while swallowing the exception and returning true otherwise.
This is not ideal.

which assert use with junit

I have to test that a method of my class return a value different from zero.my problem is that I don't know the assert I have to use.there is only assertEquals but not assertNotEquals.how can I do?
Use:
assertTrue(currentValue!=0);
Or You can switch to TestNG and there are "assertNotEquals" methods.
Use
Assert.assertTrue(actualValue!=0);
but this do not give you the informative message in case of failure
I think you use JUnit3(or higher) and you want to test if an int i != 0. You should use:
import junit.framework.TestCase;
public class Tests extends TestCase {
public void testMe(){
int i = 4;
assertNotSame("msg on fail", i, 0);
}
}
use assertNotSame for testing unequal.
Use assertNotNull for o != null
Hamcrest is your friend here. Use
assertThat(currentValue, not(equalTo(0)))
This is readable and produces a decent message in case of failure.

EasyMock : java.lang.IllegalStateException: 1 matchers expected, 2 recorded

I am having a problem with EasyMock 2.5.2 and JUnit 4.8.2 (running through Eclipse). I have read all the similar posts here but have not found an answer. I have a class containing two tests which test the same method. I am using matchers.
Each test passes when run alone.
The first test always passes - this is true if I switch the order of the tests in the file.
Here is a simplified version of the test code:
private Xthing mockXthing;
private MainThing mainThing;
#Before
public void setUp() {
mockXthing = EasyMock.createMock(Xthing.class);
mainThing = new MainThing();
mainThing.setxThing(mockXthing);
}
#After
public void cleanUp() {
EasyMock.reset(mockXthing);
}
#Test
public void testTwo() {
String abc = "abc";
EasyMock.expect(mockXthing.doXthing((String) EasyMock.anyObject())).andReturn(abc);
EasyMock.replay(mockXthing);
String testResult = mainThing.testCallingXthing((Long) EasyMock.anyObject());
assertEquals("abc", testResult);
EasyMock.verify(mockXthing);
}
#Test
public void testOne() {
String xyz = "xyz";
EasyMock.expect(mockXthing.doXthing((String) EasyMock.anyObject())).andReturn(xyz);
EasyMock.replay(mockXthing);
String testResult = mainThing.testCallingXthing((Long) EasyMock.anyObject());
assertEquals("xyz", testResult);
EasyMock.verify(mockXthing);
}
The second (or last) test always fails with the following error:
java.lang.IllegalStateException: 1 matchers expected, 2 recorded
Any insight to this would be greatly appreciated.
Thanks,
Anne
I haven't looked meticulously closely yet, but this looks suspect:
String testResult = mainThing.testCallingXthing((Long) EasyMock.anyObject());
anyObject() is a matcher and you're calling it after the replay. It's not used to produce any object. It's used to instruct EasyMock to allow any object. EasyMock is detecting that extra matcher but it is not harmful until the second test. At that point, the number of matchers that EasyMock has recorded but hasn't yet used (2) doesn't line up with the number of parameters expected for the second doXthing call (1).
You should be passing in real parameters to testCallingXthing (or a mock that is in replay mode). Try passing in null directly, or a real value like 2.
for me this failure (in my case 2 matchers expected, 4 recorded.) meant "you are mixing easymock and mockito in the same unit test, so accidentally calling easymock's notNull() method for a mockito argument. Which causes the failure but only if the tests are run in a certain order.
Try:
String testResult = mainThing.testCallingXthing(eq(EasyMock.anyLong()));
There are more refined matchers than anyObject(). These allow you to make type-based assertions about collaborators.
From the EasyMock documentation:
eq(X value)
Matches if the actual value is equals the expected value. Available for all primitive types and for objects.
anyBoolean(), anyByte(), anyChar(), anyDouble(), anyFloat(), anyInt(), anyLong(), anyObject(), anyShort()
You should reset mock after each test method to get rid of this problem. Adding below code will solve this problem.
#After
public void after(){
EasyMock.reset(mockXthing)
}

Categories