JUnit Custom Rules - junit

JUnit 4.7 introduced the concept of custom rules:
http://www.infoq.com/news/2009/07/junit-4.7-rules
There are a number of built in JUnit rules including TemporaryFolder which helps by clearing up folders after a test has been run:
#Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
There's a full list of built in rules here:
http://kentbeck.github.com/junit/javadoc/latest/org/junit/rules/package-summary.html
I'm interested in finding out what custom rules are in place where you work or what useful custom rules you currently use?

I used #Rule for repeated test: #Rule: 在JUnit4中利用Rule
Sorry, It's Chinese, but code and comment are English:)

Related

KotlinTestEngine.discover() doesn't return any tests

My goal is to have a class which can find any tests written in kotlintest. I already have working code for Java/Scala/Groovy unit tests but can't get it to work for Kotlintest.
My discover code:
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request().selectors(selectPackage("com.example")).build();
descriptor = new KotlinTestEngine().discover(request, uniqueId);
UniqueId has value of "engine:junit-example". I tried adding the following code but it doesn't work either.
new DiscoverySelectorResolver().resolveSelectors(discoveryRequest, descriptor);
The descriptor contains all the classes with tests but no test methods. In other cases it is enough to call descriptor.getChildren() to get the test methods but with Kotlintest I get empty list.
Thanks for any help.
The reason your code doesn't work is because KotlinTest doesn't honour package name selectors. This could be considered a bug in KotlinTest.
It does honour classpath, class, directory and uri selectors though.
Edit:
As of 3.2 KotlinTest now supports package selectors so your code will work.

Cocos2d-x: deprecated class Object

I'm trying to learn from a sample source code (Since the framework is utterly undocumented) that was written for cocos2d-x 3.0alpha, the code is using the deprecated class "Object", I'm trying to port the code to version 3.0 but I'm not sure which class be used instead of Object.
Do you have any idea?
https://github.com/OiteBoys/Earlybird/blob/master/Earlybird/Classes/Number.h
Edit: pretty sure the class I need is Ref
Current issue I'm trying to solve is finding the equivalent of EGLView::getInstance()
Edit II: GLView::create("view"); seems to be it.
Yes, you need Ref. Here are the release notes for Version 3.0. It describes this here. This changes was done since C++ doesn't have and doesn't need a base object. Object was created for that reason originally but now deprecated.
https://github.com/cocos2d/cocos2d-x/blob/v3/docs/RELEASE_NOTES.md
For EGLView create a quick sample "Hello World" project using the cocos command-line tool and have a look at AppController.mm, RootViewController.mm and AppDelegate.cpp. These have changed a good deal for version 3.0+.
Edit: based upon your edit look at: bool AppDelegate::applicationDidFinishLaunching()
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLView::create("My Game");
director->setOpenGLView(glview);
}

Class loading collision between Robolectric and Powermock

I'm trying to write a test that needs both Robolectric 2.2 and PowerMock, as the code under test depends on some Android libraries and third party libraries with final classes that I need to mock.
Given that I'm forced to use the Robolectric test runner through:
#RunWith(RobolectricTestRunner.class)
...I cannot use the PowerMock test runner, so I'm trying to go with the PowerMock java agent alternative, without luck so far.
I have setup everything according to this guide but I'm facing a collision problem between classes required by the javaagent library and by robolectric through its dependency with asm-1.4. Both depend on
org.objectweb.asm.ClassVisitor
, but javaagent-1.5.1 ships with its own version where ClassVisitor is an interface while asm-1.4 version for the same namespace is an abstract class, with the corresponding error at runtime:
java.lang.IncompatibleClassChangeError: class org.objectweb.asm.tree.ClassNode has interface org.objectweb.asm.ClassVisitor as super class
I have even tried to modify the javaagent library jar to entirely remove the org.objectew.asm classes in there, but that doesn't work as ClassNotFoundException happens afterwards due to some other classes needed in the org.objectweb.asm package that only ship in the javaagent library jar, and not in the asm one.
Any ideas? According to examples out there the agent seems to work fine with, at least, the Spring test runner.
I had the same problem and while I didn't solve this problem as such, I wanted to share my approach, which removes the need for PowerMock (which is always a good thing in my view): I wanted to mock a call to
Fragment fooFragment = new FooFragment();
So what I did was addanother level of indirection. I created a FragmentProvider class:
public FragmentFactory fragmentFactory = new FragmentFactory();
[...]
Fragment fooFragment = fragmentFactory.getFooFragment();
After i did this, I could just mock out the factory with standard Mockito, like this:
FragmentFactory mockFactory = mock(FragmentFactory.class);
activity.fragmentFactory = mockFactory;
when(mockFactory.getFooFragment()).thenReturn(mockFooFragment);

How to use JExample with #Rule instead of #RunWith

I need to add dependencies between behavioural-test methods where I use #RunWith(SpringJUnit4ClassRunner.class) to run the tests.
I add Mockito to the mix by using:
#Rule
public MockitoRule mockitoRule = new MockitoRule();
Where MockitoRule is a short class implementing MethodRule applying Mokito behaviour, I managed to scrounge up somewhere.
Now the question: Anyone have ideas of how I would archive a somthing similar with JExample, ie: applaying it with a #Rule instead of using the #RunWith(JExample.class)?
Looking at Sourceforge and github, it doesn't look like there has been much development in JExample in the last couple of years, so there probably isn't a #Rule for JExample. I would contact the original author to see how easy it would be to add a TestRule.
At first glance, it seems that it would require a slight change to how JExample works, because the return values of the tests are actually used, whereas the base runners for JUnit assume that the methods are void return values.

Globally setting a JUnit runner instead of #RunWith

Without looking into JUnit source itself (my next step) is there an easy way to set the default Runner to be used with every test without having to set #RunWith on every test? We've got a huge pile of unit tests, and I want to be able to add some support across the board without having to change every file.
Ideally I'm hope for something like: -Djunit.runner="com.example.foo".
I don't think this is possible to define globally, but if writing you own main function is an option, you can do something similar through code. You can create a custom RunnerBuilder and pass it to a Suite together with your test classes.
Class<?>[] testClasses = { TestFoo.class, TestBar.class, ... };
RunnerBuilder runnerBuilder = new RunnerBuilder() {
#Override
public Runner runnerForClass(Class<?> testClass) throws Throwable {
return new MyCustomRunner(testClass);
}
};
new JUnitCore().run(new Suite(runnerBuilder, testClasses));
This won't integrate with UI test runners like the one in Eclipse, but for some automated testing scenarios it could be an option.
JUnit doesn’t supporting setting the runner globally. You can hide away the #RunWith in a base class, but this probably won't help in your situation.
Depending on what you want to achieve, you might be able to influence the test behavior globally by using a custom RunListener. Here is how to configure it with the Maven Surefire plugin: http://maven.apache.org/plugins/maven-surefire-plugin/examples/junit.html#Using_custom_listeners_and_reporters