junit custom ParameterSupplier - junit

all of the samples i've seen online with regard to custom parametersuppliers have something like:
List<PotentialAssignment> list = new ArrayList<PotentialAssignment>();
list.add(PotentialAssignment.forValue("teams", "giants"));
list.add(PotentialAssignment.forValue("teams", "jets"));
list.add(PotentialAssignment.forValue("teams", "niners"));
return list;
now, the question i have is: what does the first argument to PotentialAssignment.forValue(arg1, arg2) do? Nothing i've seen online has explained the significance of it.
thanks

The first parameter of PotentialAssignment.forValue is the "name" of the value. It is not used, if your #Theory method passes, but if it fails, it is used to assemble the error message. Here is an example:
#RunWith(Theories.class)
public class CustomParameterSupplierTest {
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.PARAMETER)
#ParametersSuppliedBy(FooSupplier.class)
public #interface Foo {}
public static class FooSupplier extends ParameterSupplier {
#Override
public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
return Arrays.asList(
PotentialAssignment.forValue("one", 1),
PotentialAssignment.forValue("two", 2)
);
}
}
#Theory
public void test(#Foo int foo) {
assertThat(foo, is(1));
}
}
If this test is executed with Junit 4.11 you will get the following error:
org.junit.experimental.theories.internal.ParameterizedAssertionError: test(two)
By the way, in the upcoming release JUnit 4.12 the error reporting is further improved and you will get the following error:
org.junit.experimental.theories.internal.ParameterizedAssertionError: test("2" <from two>)

Related

Why Junit assertThat() passes for two objects depsite the objects being unequal?

I am comparing two objects emsResponse and expectedEMSResponse of the same class EMSResponse in a Junit test case but the assertThat(...) test case passes despite the objects being unequal. When I try a normal equals on the two objects the output is false but the assertThat(expectedEMSResponse==eMSResponse) still passes rather than failing. Please advise.
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#ToString
#EqualsAndHashCode
public class RestconfRes {
private String response;
private int httpStatusCode;
}
#Getter
#Setter
#ToString
#EqualsAndHashCode(callSuper = true)
public class EMSResponse extends RestconfRes {
private EMSOutput output;
private EMSErrors errors;
private String message;
public EMSOutput getOutput() {
if (output == null) {
output = new EMSOutput();
}
return output;
}
}
// Junit test case
#Test
public void processJMSRequestForHappyPathTest() throws Exception {
// test case logic here
// mock logic here
EMSResponse emsResponse = processor.processJMSRequest(request);
System.out.println(" expectedEMSResponse ..." + EMSResponse.toString());
System.out.println(" processJMSRequestForHappyPathTest expectedEMSResponse ...:" + expectedEMSResponse.toString());
System.out.println("check if i am equal..."+ expectedEMSResponse.equals(emsResponse));
assertThat(expectedEMSResponse==eMSResponse);
}
Output:
expectedEMSResponse ...EMSResponse(output=EMSoutput(deviceName=null, timestamp=null, status=failure, transId=null, completionStatus=null, serviceId=null, contentProviderName=null, interfaceName=null), errors=EMSerrors(errorType=INTERNAL_FAILURE, errorTag=A41_INTERNAL_EXCEPTION, errorMessage=An internal error occurred within A41. Please contact ASG.), message=null)
emsResponse ...EMSResponse(output=EMSoutput(deviceName=device_3, timestamp=2020-07-15T16:32:31.881000, status=configuring, transId=66427-d8b5-489f-9f8f, completionStatus=in-progress, serviceId=null, contentProviderName=null, interfaceName=null), errors=null, message=null)
check if i am equal...false
Updated second sub question to this
I changed the call to:
assertTrue(expectedEMSResponse==emsResponse);
// gives a java.lang.AssertionError and
System.out.println("check if i am equal..."+ expectedEMSResponse.equals(emsResponse)); gives output
check if i am equal...false
// this test case passes Ok assertThat(emsResponse.getOutput().getTransId()).isEqualTo(expectedEMSResponse.getOutput().getTransId());
When I try printing the details of the emsResponse and expecteEMSResponse classes through toString() I get the below output:
// gives only a bean as an output
emsResponse.toString():com.myorg.myapp.interfaces.dto.emsResponse#0 bean
//gives the complete object signature
expectedemsResponse.toString():emsResponse(output=emsOutput(deviceName=device_3,
timestamp=2020-07-15T16:32:31.881000, status=configuring, transId=hello-there-489f-9f8f-abcd,
completionStatus=in-progress, serviceId=null, contentProviderName=null, interfaceName=null), errors=null, message=null)
You are probably using AssertJ because I don't think JUnit 4 or Hamcrest have a single argument version of assertThat(), and JUnit 5 doesn't have such method.
The way AssertJ assertThat() works is that the first argument of the call is the actual value that you want to perform assertions on. This returns an assertion object, which provides you a number of assertion methods.
When you call assertThat(expectedEMSResponse==eMSResponse), AssertJ just returns an assertion object for boolean type and nothing else happens.
The correct way to use it would be:
assertThat(eMSResponse).isEqualTo(expectedEMSResponse);
Now it returns an assertion object for the first argument, and then performs the isEqualTo() assertion on that one. The assertThat() call only works as an entry point to different assertions that can be performed on the first argument.
I don't think you are using assertThat correctly. Looks like you need to pass additional arguments as well. These are the method definitions:
assertThat(T actual, Matcher<? super T> matcher)
assertThat(String reason, T actual, Matcher<? super T> matcher)
Also as per the documentation, it is deprecated. Might I suggest that you use assertEquals() instead?
The documentation: https://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat
This does not fail because you are not using junit correctly:
#Test
public void processJMSRequestForHappyPathTest() throws Exception {
// test case logic here
// mock logic here
EMSResponse emsResponse = processor.processJMSRequest(request);
System.out.println(" expectedEMSResponse ..." + EMSResponse.toString());
System.out.println(" processJMSRequestForHappyPathTest expectedEMSResponse ...:" + expectedEMSResponse.toString());
System.out.println("check if i am equal..."+ expectedEMSResponse.equals(emsResponse));
assertThat(expectedEMSResponse==eMSResponse);
}
You should have:
assertTrue(expectedEMSResponse==eMSResponse);
assertEquals(expectedEMSResponse, eMSResponse);
Or using assertThat with assertj:
assertThat(eMSResponse).isEqualTo(expectedEMSResponse);
This should help you understand:
junit 5: https://junit.org/junit5/docs/current/user-guide/
junit 4: https://www.baeldung.com/junit-assertions

Is it possible to name a test suite in JUnit 4?

In JUnit3, one would could name a test suite like this:
public static Test suite() {
TestSuite suite = new TestSuite("Some test collection");
suite.addTestSuite(TestX.class);
return suite;
}
Is there an equivalent way to do this in JUnit4?
Thanks.
EDIT
Thank you, I actually managed to get it working. My question was if there is a JUnit4 equivalent way of specifying the name/description of a test suite, like in JUnit3 with "Some test collection".
Some background:
I'm converting junit tests in legacy code to the version 4, and I don't want to lose any information if possible. I apologize, I should really have been more specific in the original question.
You can do this with the Suite runner #RunWith(Suite.class):
#RunWith(Suite.class)
#SuiteClasses({Test1.class, Test2.class, TestX.class})
public class MySuite {}
Where Test1, Test2, TestX contain your tests
ref. RunWith, Suite
update:
WRT changing the actual description of your suite, I don't think there's a way to do it out-of-the-box (if there is I haven't seen it yet). What you can do, is to define your own runner with a custom description [update2]:
#RunWith(DescribedSuiteRunner.class)
#SuiteClasses({Test1.class, Test2.class, TestX.class})
#SuiteDescription("Some test collection")
public class MySuite {}
public class DescribedSuiteRunner extends Suite {
// forward to Suite
public DescribedSuiteRunner(Class<?> klass, RunnerBuilder builder)
throws InitializationError {
super(klass, builder);
}
#Override
protected String getName() {
return getTestClass()
.getJavaClass()
.getAnnotation(SuiteDescription.class)
.value();
}
}
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface SuiteDescription {
String value();
}
The default implementation of getName just returns the class being tested's name
Yes, In JUnit 3.x, the JUnit methods had to be specifically named. They needed to begin with the word test in order for JUnit to run that as a test case. Now you can just use the #Test annotation:
#Test
public void thisIsMyTest() {
// test goes here
}
Also in JUnit4 you can state if you want some tests to run before or after all the tests in this class are invoked:
#Before
public void init() throws Exception {
System.out.println("Initializing...");
}
#After
public void finish() throws Exception {
System.out.println("Finishing...");
}
Further comparisons between JUnit3 and JUnit4 here and here.
Edit: after blgt's comment, I see I might have misunderstood your intent.
You are probably looking for #RunWith(Suite.class) - When a class is annotated with #RunWith, JUnit will invoke the class in which is annotated so as to run the tests, instead of using the runner built into JUnit. Full example of usage is here, tl;dr below:
#RunWith(Suite.class)
#SuiteClasses({ FirstTest.class, SecondTest.class })
public class AllTests {
...
}

Castle Windsor Resolve method: why pass arguments? What are they for?

I am confused by Castle Windsor resolve method. This method allows me to pass almost anything. Is the value submitted in the resolve method passed along and used in the constructor of the object which is eventually resolved to, or is this value used to help the resolver determine what concrete implementation to use?
For example, if I have the following snippet...
var _container = new WindsorContainer();
_container.Install(FromAssembly.This());
var MyProcessor = _container.Resolve<IProcessor>(new Arguments(new {"Processor1"}));
assuming I have two concrete implementations of IProcessor - like Processor1:IProcessor, and/or Processor2:IProcessor. What are the 'Arguments' used for?
I understand the...
Component.For<IProcessor>()
... needs to be defined, but I am struggling with the terms the Windsor folks choose to use (i.e. DependsOn, or ServicesOverrides) and the intent. Given the method is called 'resolve' I can only image any values passed to this will be used to resolve the decision on which concrete implementation to use. Is this assumption wrong?
The arguments parameter you're talking about is for providing arguments to components that can't be satisfied by Windsor components. The anonymous types overloads as well as the dictionary overalls I believe are all for this purpose. I've used this in the past, and I don't recommend it as it leads to poor patterns like Cristiano mentioned... and last time I used this it only works for the component being directly resolved. Anyway... here's an example of how this works:
[TestFixture]
public class Fixture
{
[Test]
public void Test()
{
IWindsorContainer container = new WindsorContainer();
container.Register(Component.For<IFoo>().ImplementedBy<Foo>().LifeStyle.Is(LifestyleType.Transient));
Assert.Throws<HandlerException>(() => container.Resolve<IFoo>());
IFoo foo = container.Resolve<IFoo>(new {arg1 = "hello", arg2 = "world"});
Assert.That(foo, Is.InstanceOf<Foo>());
Assert.That(foo.ToString(), Is.EqualTo("hello world"));
}
}
public interface IFoo
{
}
public class Foo : IFoo
{
private readonly string _arg1;
private readonly string _arg2;
public Foo(string arg1, string arg2)
{
_arg1 = arg1;
_arg2 = arg2;
}
public override string ToString()
{
return string.Format("{0} {1}", _arg1, _arg2);
}
}
I am awarding the answer to kellyb for the awesome example. During investigation, using Castle.Windsor 3.2.1, I found at least 2 reasons for passing a value in the "resolve" method.
To satisfy intrinsic type dependencies, such as strings, or integers in
the object resolved by the use of the "Resolve" method - as
described in kellyb's example.
To help Castle identify which concrete implementation to select.
to help illustrate both uses I am elaborating on the example provided above by kellyb.
Synopsis - or test condition
Assume there is one interface called IFoo and two concrete implementations that derive from this interface called Foo and Bar. A class called Baz is defined but does not derive from anything. Assume Foo requires two strings, but Bar requires a Baz.
Interface IFoo Definition
namespace CastleTest
{
public interface IFoo
{
}
}
Class Foo Definition
namespace CastleTest
{
public class Foo : IFoo
{
private readonly string _arg1;
private readonly string _arg2;
public Foo(string arg1, string arg2)
{
_arg1 = arg1;
_arg2 = arg2;
}
public override string ToString()
{
return string.Format("{0} {1}", _arg1, _arg2);
}
}
}
Class Bar Definition
namespace CastleTest
{
class Bar : IFoo
{
private Baz baz;
public Bar(Baz baz)
{
this.baz = baz;
}
public override string ToString()
{
return string.Format("I am Bar. Baz = {0}", baz);
}
}
}
Class Baz Definition
namespace CastleTest
{
public class Baz
{
public override string ToString()
{
return "I am baz.";
}
}
}
The Test (Drum roll, please!)
kellyb's example test shows an assert that expects a failure if args is not supplied. kellyb's example does not have multiple implementations registered. My example has multiple implementations registered, and depending on which is marked as the default this assert may or may not fail. For example, if the concrete implementation named "AFooNamedFoo" is marked as default, the assert completes successfully - that is to say the resolution of an IFoo as a Foo does indeed require args to be defined. If the concrete implementation named "AFooNamedBar" is marked as default, the assertion fails - that is to say the resolution of an IFoo as a Bar does not require args to be defined because its dependency of a Baz is already registered (in my example where multiple concrete implementations are registered). For this reason, I have commented out the assert in my example.
using Castle.Core;
using Castle.MicroKernel.Handlers;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using NUnit.Framework;
namespace CastleTest
{
[TestFixture]
public class ArgsIdentifyConcreteImplementation
{
[Test]
public void WhenSendingArgsInResolveMethodTheyAreUsedToIdentifyConcreteImplementation()
{
IWindsorContainer container = new WindsorContainer();
container.Register(Component.For<IFoo>().ImplementedBy<Foo>().LifeStyle.Is(LifestyleType.Transient).Named("AFooNamedFoo"));
container.Register(Component.For<IFoo>().ImplementedBy<Bar>().LifeStyle.Is(LifestyleType.Transient).Named("AFooNamedBar").IsDefault());
container.Register(Component.For<Baz>().ImplementedBy<Baz>().LifeStyle.Is(LifestyleType.Transient));
// THIS ASSERT FAILS IF AFooNamedBar IS DEFAULT, BUT
// WORKS IF AFooNamedFoo IS DEFAULT
//Assert.Throws<HandlerException>(() => container.Resolve<IFoo>());
// RESOLVE A FOO
IFoo foo = container.Resolve<IFoo>("AFooNamedFoo", new { arg1 = "hello", arg2 = "world" });
Assert.That(foo, Is.InstanceOf<Foo>());
Assert.That(foo.ToString(), Is.EqualTo("hello world"));
// RESOLVE A BAR
IFoo bar = container.Resolve<IFoo>("AFooNamedBar");
Assert.That(bar, Is.InstanceOf<Bar>());
Assert.That(bar.ToString(), Is.EqualTo("I am Bar. Baz = I am baz."));
}
}
}
Conclusion
Looking at the test above, the resolution of a Foo object has two things passed in the "resolve" method - the name of the implementation, and the additional string dependencies as an IDictionary object. The resolution of a Bar object has one thing passed in the "resolve" method - the name of the implementation.
In fact you should not call Resolve ever in your code rather than in the Composition root and also there you should not need to supply parameters to the Resolve method.
Custom resolution strategies should be done through installers, factories/ITypedFactoryComponentSelector, subresolvers... see documentation for more details on those options
BTW through "Resolve" parameters you can identify the component to resolve(by name or type) and its own direct dependencies.

Cant mock static functions with powermock-easymock-testng (non-maven project)

To tell you first, i have tried and tried it again and now i need some help
Heres my code
package staticPkg;
public class Static {
public static final String staticMethod() {
System.out.println("Static method called");
return "Static called";
}
}
package staticPkg;
public class TargetClass {
Static staticClass;
public String callHere() {
return Static.staticMethod();
}
}
package staticPkg;
import org.easymock.EasyMock;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.testng.IObjectFactory;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
#PrepareForTest({Static.class})
public class TestClass {
Static staticClass = null;
#ObjectFactory
public IObjectFactory getObjectFactory() {
System.out.println("got object factory");
return new org.powermock.modules.testng.PowerMockObjectFactory();
}
#BeforeMethod
public void setup() {
System.out.println("print me");
PowerMock.mockStatic(Static.class);
staticClass = PowerMock.createMock(Static.class);
}
#Test
public void testMe() {
EasyMock.expect(Static.staticMethod()).andReturn("Mock called").anyTimes();
PowerMock.replay(Static.class,staticClass);
TargetClass tc = new TargetClass();
String output = tc.callHere();
PowerMock.verify(Static.class,staticClass);
System.out.println(output);
}
}
And heres the log
[Parser] Running:
C:\MockWorkspace\Mock\temp-testng-customsuite.xml
got object factory
print me
Static method called
FAILED: testMe
java.lang.IllegalStateException: no last call on a mock available
at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:521)
at org.easymock.EasyMock.expect(EasyMock.java:499)
at staticPkg.TestClass.testMe(TestClass.java:46)
... Removed 22 stack frames
===============================================
staticPkg.TestClass
Tests run: 1, Failures: 1, Skips: 0
===============================================
===============================================
Mock
Total tests run: 1, Failures: 1, Skips: 0
===============================================
Help please, i have tried a variety of solutions, can't get it done.
Please can anyone try this code and correct it for success?
I get error in EasyMock.expect ...............
Got a work around at http://blogs.bytecode.com.au/glen/2006/10/12/doing-bytecode-kungfu-with-javassist.html
And it works
But wait..........I am stuck again
My testcase works fine when runs alone, but when run with Ant, it gives problem. Might be other test cases of different files are interfering.
I got the same error, when my individual test case was using #PrepareTest & easymock/powermock
[testng] ====================STATIC CALLED===========================
[testng] javassist.CannotCompileException: by java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClass
Loader): attempted duplicate class definition for name: "com/symantec/mobius/aggregator/submission/SubmissionFactory"
[testng] at javassist.ClassPool.toClass(ClassPool.java:1085)
[testng] at javassist.ClassPool.toClass(ClassPool.java:1028)
[testng] at javassist.ClassPool.toClass(ClassPool.java:986)
[testng] at javassist.CtClass.toClass(CtClass.java:1110)
Try extending from PowerMockTestCase. The TestNG support will also be updated in next version of PowerMock (1.4.9).
I faced this same issue, and struggled a lot. Finally, found the following solution:
Another alternative is to set the object-factory to org.powermock.modules.testng.PowerMockObjectFactory in the TestNG suite.xml. Here is a sample suite file:
<suite name="dgf" verbose="10" object-factory="org.powermock.modules.testng.PowerMockObjectFactory">
<test name="dgf">
<classes>
<class name="com.example.ClientTest"/>
</classes>
</test>
</suite>
Of course, you can also extend your test case from PowerMockTestCase as told by Johan.
Mock all the static methods in static class before proceeding to mock the static method. Try with this:
#Test
public void testMe() {
PowerMock.mockStatic(Static.class);
EasyMock.expect(Static.staticMethod()).andReturn("Mock called").anyTimes();
PowerMock.replay(Static.class,staticClass);
TargetClass tc = new TargetClass();
String output = tc.callHere();
PowerMock.verify(Static.class,staticClass);
System.out.println(output);
}

Passing command line arguments to JUnit in Eclipse

All,
I am currently using JUnit 4 for writing test cases. I am fairly new to JUnit and finding it difficult to test my main class which takes arguments. I have specified the arguments to my JUnit test class by:
1 > Right click JUnit test class
2 > Goto Run As -> Run Configurations
3 > Select the Arguments tab and specify a value (I have entered an invalid argument i.e. the main class expects the command line argument to be converted to an int and I am passing a String value that cannot be converted to int)
However, the main class that I am testing, if the command line argument cannot be converted to a int, than I throw IllegalArgumentException. However, the JUnit does not show the testMain() method as Error or Failure. I don't think my setup is right for the JUnit class. Can anyone please guide me where I am going wrong
To test your class main method simply write something like:
#Test(expected = IllegalArgumentException.class)
public void testMainWithBadCommandLine()
{
YourClass.main(new String[] { "NaN" });
}
Change the main() method to something like this:
public static void main(String[] args)
{
MyClass myclass = new MyClass(args);
myclass.go();
}
Move the code that was in main() to the new method go(). Now, your test method can do this:
public void myClassTest()
{
String[] args = new String[]{"one", "two"}; //for example
MyClass classUnderTest = new MyClass(testArgs);
classUnderTest.go();
}
Firstly the arguments should be in the program arguments section. Normally the launching point of the application that's the main method doesn't need to be tested if you design the app to be testable.
Refactor the class
public static class ArgumentValidator
{
public static boolean nullOrEmpty(String [] args)
{
if(args == null || args.length == 0)
{
throw new IllegalArgumentException(msg);
}
//other methods like numeric validations
}
}
You can now easily test the nullOrEmpty method using junit like
#Test(expected = IllegalArgumentException.class)
public void testBadArgs()
{
ArgumentValidator.nullOrEmpty(null);
}
I think this is a better approach