Is it possible to find current JUnitParams parameters from a custom rule? - junit4

I started using JUnitParams to write parameterized tests and it works awesome. For example, the following test is invoked with false, then with true:
#Test
#Parameters ({ "false", "true" })
public void testBla (boolean foo) throws Exception
...
One minor trouble is that I have a custom rule (as in org.junit.rules.TestRule) that only exists to write some additional information to the logs. What it currently does is
public Statement apply (final Statement statement, final Description description)
{
return new Statement ()
{
public void evaluate () throws Throwable
{
log.info (String.format ("RUNNING TEST %s::%s\n",
description.getClassName (),
description.getMethodName ()));
...
When I have just two parameters as above, it is not a problem that it writes the same name for two executions of one method, I can simply count. However, it would still be useful for the rule to print parameter values, especially if I have more.
So, is it possible to find test parameters from within a custom rule?

my best guess: most parameterized junit plugins using junit's Description object. you should be able to get this object in your rule. but what is in this object and is it enough for your purpose depends on the specific plugin you use. if this one is not good for you, try others

Related

Is there any alternative to [OneTimeSetup] in Nunit?

In my existing [OneTimeSetup] method, I want to check some preconditions before running any test. But I can't do so as the object which I'll be needing to check preconditions is initialized in Base class [Setup] method. I can't initialize this earlier due to some project limitations.
So, Is there any way where I can execute some code after Base [Setup] method (to check some preconditions) and before any suite execution? I want to execute this once per suite.
[SetUpFixture]
Class GlobalSetup
{
[OneTimeSetUp]
public void OneTimeSetUp(){
setup();
CheckIfDataIsPresent(); // I can't do this here as this code needs Obj O to be initialized. which will be initialized in Base class's [Setup] methed
}
}
Public class Base
{
[Setup]
public void setUp()
{
//some code where we initialize obj O;
}
}
[TestFixture]
public class Test : Base
{
// tests to be executed
}
You already did a nice job of explaining why what you want to do won't work, so I don't have to. :-)
The problem is that each your tests needs a fresh instance of that object, so you properly create it in a [SetUp] method. You would like to ensure that it's possible to create such an object once before you run any tests.
I can only give you a non-specific answer, since you haven't given a lot of info in your example code. If you update your question, I may be able to update my answer. Here goes...
Both your tests and the check you want to perform require an instance of object o. So one approach would be to initialize o one more time in the OneTimeSetup, perform the check and then throw it away. Since you are initializing o in every test, I assume it's not expensive to do so. Say you have 100 tests. You are setting up o 100 times. So make it 101 and be done!
Alternatively, determine what is required for o to be initialized successfully and check that. For example, if it needs a file to be present, check that the file is present. If the file has to have 100 records in some format, check that it's so. Perhaps you might give us more detail about what those prerequisites are.
Finally, you might reconsider whether you really need a new instance per test. Since you suggest you would be willing to make a check once per fixture (I assume that's what you mean by suite) then perhaps you really only need one instance per fixture rather than a new one for each test.

Registering a type with both EnableClassInterceptors and WithParameter

I'm having an issue with Autofac where it seems like EnableClassInterceptors is interfering with my ability to use .WithParameter(...). When the constructor is being called on Service using the code below, someString is not being populated. Notes:
I've tried using ResolvedParameter instead, it does not help (note: my Resolved parameter still includes the name of the parameter when I tried that)
If I remove EnableClassInterceptors and InterceptedBy, the parameter does get populated properly. This, however, isn't a valid solution as I need the interceptors.
Re-ordering WithParameter, EnableClassInterceptors, and InterceptedBy does not help.
Looking at Type Interceptors, specifically the "Class Interceptors and UsingConstructor" section, on docs.autofac.org, it mentions that using EnableClassInterceptors will cause ConstructUsing to fail. I think something similar might be happening with my scenario below.
Snippet of my registration code looks like this:
var builder = new ContainerBuilder();
builder.RegisterType<Dependency>.As<IDependency>.InstancePerLifetimeScope();
builder.RegisterType<Service>()
.As<IService>()
.WithParameter(new NamedParameter("someString", "TEST"))
.EnableClassInterceptors()
.InterceptedBy(typeof(LogExceptionsInterceptor));
Service's constructor looks something like this:
public class Service : IService
{
public Service(IDependency dependency, string someString)
{
if(dependency == null)
throw ArgumentNullException(nameof(dependency));
if(someString == null)
//**throws here**
throw ArgumentNullException(nameof(someString));
}
}
[Guess] What I'm thinking is happening is that when EnableClassInterceptors is called, a proxy class is generated with a constructor that works on top of the existing one, but the parameter names do not copy over into the proxy class/constructor.
Is this a problem? Is there a way to form the registration that allows both WithParameter and EnableClassInterceptors to be used together? Is it a bug in Autofac?
Your guess is correct: the generated proxy class does not keep the constructor parameter names.
Currently there is no way to influence this in DynamicProxy so this is not a bug of Autofac (although this edge case currently not documented on the Autofac documentation website).
This is how your original Service class's parameters look like:
typeof(Service).GetConstructors()[0].GetParameters()
{System.Reflection.ParameterInfo[2]}
[0]: {ConsoleApplication10.IDependency dependency}
[1]: {System.String someString}
But the generated proxy does not keep the names:
GetType().GetConstructors()[0].GetParameters()
{System.Reflection.ParameterInfo[3]}
[0]: {Castle.DynamicProxy.IInterceptor[] }
[1]: {ConsoleApplication10.IDependency }
[2]: {System.String }
So you have two not very robust options to workaround this limitation with WithParameter:
use the TypedParamter with string as the type:
.WithParameter(new TypedParameter(typeof(string), "TEST"))
However if you have multiple paramters with the same type this won't work
use the PositionalParameter in this case you need to add 1 if the type is proxied
.WithParameter(new PositionalParameter(2, "TEST"))
Another options would be to don't use a primitive string type but create a wrapper e.g. MyServiceParameter or create another service which can provide these string configuration values to your other services.

How to test default case when using Junit Parameterized.class

I have an old version API: Foo(). Now I extend the API to Foo(false), Foo(true) and Foo() should still work as before.
Right now I am using Parameterized.class to do Junit, and the parameter list is {null, false, true}. I want to write the testcase as:
#Test
public void fooTest() {
Foo(parameter);
}
But Foo(parameter) cannot test Foo(), so I have to write the test code as:
#Test
public void fooTest() {
if (parameter == null)
Foo();
else
Foo(parameter);
}
Is there any simple way to write the test case so that I do not need to check whether parameter is null or not? I ask this because the original test cases before I extend API are already there in many places (see below) and I do not want to change the test code too much. :
#Test
public void fooTest() {
Foo();
}
One way could be to put the Foo-Object (instead of the constructor arguments) into the parameters, i.e. {Foo(false), Foo(true),Foo()} instead of {null, false, true}
Yet review your example. Probably it is an abstraction of a real problem. If not:
assertions are missing, these should be contained in the parameters (otherwise you get the if-problem in the assertion phase).
testing with 3 parameter values is easier done with 3 simple (un-parameterized) unittests
And you could of course put your default constructor into a separate (un-parametereized) test class.
Which alternative is the best depends heavily on the real problem behind your abstraction.

How do I debug generic methods in Eclipse?

I'm in a generic method, debugging, but i get no information about variables, can't execute statements using ctrl-shift-i, eclipse tells the that the method ... isn't available on the type T.
I can't believe it's meant to (not) work like this ...
[edit]
I'm using the eclipse that's part of RAD 7.5.4
[another edit]
Here's some code but I doubt you'll get any info from this
public abstract class GenericGroupController<T extends Group> {
...
public String addUser(final Model model, final Long id, final WebRequest request) {
T group = groupManager.loadGroup(id);
...
// this method will fail if i highlight and click ctr-shift-i
// but it will work otherwise (actually so will the method above
// because that's generic as well)
Long groupId = group.getId();
...
return getAddUserView();
}
}
If you are able to debug, as in see a stack trace, you can always see the variables in the variables window if not in the code. A lot of places where the code isn't available you can do the same. It isn't nice, but, it gets the job done.

How to access the NUnit test name programmatically?

Is there some global state somewhere that I can access the currently-running test name?
I have tests which output files into a directory and read them back in. I'd like each test to create a directory to play in and then clean up after itself, and I don't want to push that name in (I'd have to make it unique, and then make sure each test keeps it unique; ew). I could use a GUID, but I'd like helper methods to be able to assume "this is the place where test files should be stored" without having to push that GUID around to them. Again, this augers for a global state somewhere.
Basically, I want a call like TestRunner.Current.CurrentTest.Name. Does such a thing exist?
(Assuming c#)
NUnit.Framework.TestContext.CurrentContext.Test.Name
or
NUnit.Framework.TestContext.CurrentContext.Test.FullName
or if you are really lazy and aren't driving your tests with TestCaseSource (thanks #aolszowka):
this.GetType().ToString()
I haven't upgraded to 2.5.7 yet myself, but it includes a TestContext class that seems to provide just what you're looking for: http://www.nunit.org/index.php?p=releaseNotes&r=2.5.7
Assuming one method per Test, in your NUnit code, you can use reflection to get the method name from the stacktrace.
If you write a helper method in your NUnit code called by other methods to do this file logging, you can use this syntax to check for the previous method:
string MethodName = new StackFrame(1).GetMethod().Name;
See the answers to question 44153, "Can you use reflection to find the name of the currently executing method?" for more details.
If we are using TestCaseSource tag then above solutions might not give correct answer
Try using TestContext.CurrentContext.Test.MethodName
Follow the below example
namespace NunitTests
{
public class Class1
{
static List<TestData> Data = new List<TestData>()
{
new TestData()
{
...
}
};
[Test]
[TestCaseSource(nameof(TenMBInstance))]
public void TestCase(TestData value)
{
TestContext.CurrentContext.Test.Name; //TestCase(NunitTests..TestData)
TestContext.CurrentContext.Test.MethodName; //TestCase
}
}
}