Android-JUnit5 No instrumentation registered! when getting context - junit

I know this is "common" error but I am trying to make a JUnit5 Android Room test working.
I found out that JUnit5 does not support the instrumentation test (or google does not support JUnit 5 I should say) but I discovered that https://github.com/mannodermaus/android-junit5 is supposed to help me.
I modified my graddle to have the plugin added in my module and the classpath at the top of the project.
classpath("de.mannodermaus.gradle.plugins:android-junit5:1.7.1.1")
id("kotlin-android")
I also added the specific dependencies from it
androidTestImplementation("de.mannodermaus.junit5:android-test-core:1.2.2")
androidTestRuntimeOnly("de.mannodermaus.junit5:android-test-runner:1.2.2")
And in the android defaultConfig of my module I added
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArgument("runnerBuilder", "de.mannodermaus.junit5.AndroidJUnit5Builder")
The graddle builds fine but the issue is when I run my simple test
class DbTest
{
private lateinit var myDao : MyDao
#BeforeEach
fun init()
{
val context : Context = ApplicationProvider.getApplicationContext();
val db = Room.inMemoryDatabaseBuilder(
context,
ConfigDatabase::class.java).build()
tcdDao = db.getMyDao()
}
[...]
}
The error occurs when I get the context :
No instrumentation registered! Must run under a registering instrumentation.
I want to specify that I cannot use JUnit4.
Am I missing something ? Can I actually test my database with JUnit5 ? Or should I use another solution ?

Related

Is it possible to add Junit5 extensions programmatically to a #TestTemplate test using #RegisterExtension?

Using Junit version 5.9.2 I am trying to programmatically add parameter resolvers extension for a test class constructor with a #TestTemplate annotation.
I am trying to add the extensions programmatically using #RegisterExtension.
Example:
public class MyTestClass {
#RegisterExtension
static final TestDependencyResolver resolverExt = new TestDependencyResolver(/*...*/);
private final TestDependency dependency;
public MyTestClass(TestDependency dependency) {
this.dependency = dependency;
}
#TestTemplate
#ExtendWith(SomeContextProvider.class)
void test() {
//...
}
}
I have tried:
making resolverExt field non static
Movine #ExtendWith(SomeContextProvider.class) to class level
And other possible combinations of 1 and 2.
In all cases the ctor parameter dependency is not injected and TestDependencyResolver::resolveParameter is not called, which to my understanding means the object was created without/before registering TestDependencyResolver, please correct me if I am wrong.
Is what I am trying to achieve possible? thanks.
Turns out the issue was not Junit5 but TestTemplateInvocationContextProvider I was using.
I used PactVerificationInvocationContextProvider which seems to have a bug and throws NullPointerException when resolving Ctor params, I have opened an issue for it if you want more details.

Startup.cs error (ASP.Net Core configuration)

I am trying to set up an ASP.Net Core application to read in configuration settings from a json file. I am using VS2015 and .NetCore 1.0 (with .Net Core Tools preview 2). I am having problems getting a simple piece of boiler plate code to compile.
I am using the following code, which was published at
http://asp.net-hacker.rocks/2016/03/21/configure-aspnetcore.html
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables();
if (env.IsDevelopment())
{
// This will push telemetry data through Application Insights
// pipeline faster, allowing you to view results immediately.
builder.AddApplicationInsightsSettings(developerMode: true);
}
Configuration = builder.Build();
}
However, the IDE/compiler complains that 'the name "Configuration" does not exist in the current context' (last line of code). The only suggestion from the IDE is to include Microsoft.Extensions.Configuration. However this is a namespace which does not contain an object or property named "Configuration".
In addition 'AddApplicationInsightsSettings' fails with does IConfigurationBuilder not contain a definition for AddApplicationInsightsSettings and no extension method AddApplicationInsightsSettings accepting a first argument of type IConfigurationBuilder could be found
Any suggestions please ?
Thanks
Simply add Configuration property to your Startup class, tutorial has missed this 'step':
public IConfigurationRoot Configuration { get; set; }
ConfigurationBuilder.Build() method just returns instance of IConfigurationRoot, that you should save, if need to get settings further in Startup class (in ConfigureServices method for example).
Regarding second error, looks like you didn't add the Application Insights dependency:
{
"dependencies": {
"Microsoft.ApplicationInsights.AspNetCore": "1.0.0"
}
}

Issue with mysql connection while running JUnit test with play2 framework

I'm currently creation JUnit test for a play application. The problem comes when I try to use FakeApplication. I create one in JUnit test but when a test uses the fakeApplication instance, then I got this:
[error] Test controllers.MyClassTest.getMyProperty failed: play.api.Configuration$$anon$1: Configuration error[Cannot connect to database [default]]
Here's my Java code in the JUnit test class:
...
#BeforeClass
public static void startFakeApplication() {
Map<String, String> settings = new HashMap<String, String>();
settings.put("db.default.url", "jdbc:mysql://myhost/releaseDB?characterEncoding=UTF-8");
settings.put("db.default.driver", "com.mysql.jdbc.Driver");
settings.put("db.default.user", "release");
settings.put("db.default.password", "release");
settings.put("db.default.jndiName", "DefaultDS");
Helpers.start(fakeApplication);
}
...
Then my method to test (notice the dummy run so nothing should cause any trouble):
...
public void getMyProperty() {
Helpers.running (fakeApplication, new Runnable() {
public void run() {
}
});
}
...
I think the problem is a database connection issue, and of course when running play in run mode, everything is fine. If I don't use FakeApplication then it's fine also but I need it.
All the database information in startFakeApplication method are coming from conf/application.conf so they're right.
What is strange is that I also have this line in the output screen when running test:
[info] play - datasource [jdbc:mysql://myhost/releaseDB?characterEncoding=UTF-8] bound to JNDI as DefaultDS
Did I missed something important here ?
Thx
Are you passing your settings map to fakeApplication somewhere? Something like:
FakeApplication fakeApplication = fakeApplication(settings);
An alternative option is to have a separate application-test.conf file and include the following in your build.sbt file:
javaOptions in Test ++= Seq(
"-Dconfig.file=conf/application-test.conf"
)
My framework Acolyte provides a JDBC driver & tools, designed for such purposes (mock up, testing, ...): http://acolyte.eu.org
It's used already in some open source projects (Anorm, Youtube Vitess, ...), either in vanilla Java, or using its Scala DSL.
val jdbcUrl = "jdbc:acolyte:anything-you-want?handler=my-unique-id"
val handler = handleStatement.withQueryDetection(...).
withQueryHandler(/* which result for which query */).
withUpdateHandler(/* which result for which update */).
// Register prepared handler with expected ID 'my-unique-id'
acolyte.Driver.register("my-unique-id", handler);
// then ...
Connection con = DriverManager.getConnection(jdbcUrl);
// ... Connection |con| is managed through |handler|
// Or pass the JDBC url to Play config

Resolve caste windsor failing

Recently upgraded to version 3.2.1 of castle windsor and receiving an error when attempting to resolve a service that previously didn't occur in version 3.0 of the windsor framework.
IWindsorContainer container = new WindsorContainer();
The following code no longer works
// Throws component not found exception
InstallerHelper.ProcessAssembliesInBinDirectory(
assembly => container.Register(
Classes
.FromAssembly(assembly)
.BasedOn<IWindsorInstaller>()
.WithService.FromInterface()
.LifestyleSingleton()
));
var installers = container.ResolveAll<IWindsorInstaller>();
container.Install(installers);
// Fails here, is it related to a hashcode mismatch in SimpleTypeEqualityComparer?
var credentialCache = container.Resolve<ICredentialCache>()
// works fine if explicity install installers individually
container.Install(new CredentialsInstaller());
var credentialCache = container.Resolve<ICredentialCache>()
Where ProcessAssembliesInBinDir is:
public static void ProcessAssembliesInBinDirectory(Action<Assembly> action)
{
var directoryName = GetDirectoryName();
foreach (var dll in Directory.GetFiles(directoryName, "*.dll"))
{
var fileInfo = new FileInfo(dll);
if (!IgnoreList.Any(x=>fileInfo.Name.StartsWith(x)))
{
var assembly = Assembly.LoadFile(dll);
action(assembly);
}
}
}
Where credential installer is:
public class CredentialsInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ICredentidalCache>()
.ImplementedBy<CredentidalCache>()
.LifestyleSingleton()
);
// This works fine
var credentialCache = container.Resolve<ICredentialCache>()
}
}
Class implementation
public interface ICredentidalCache {}
public class CredentidalCache : ICredentidalCache{}
This is being run from an MVC application
version 4.5 of the .net framework
the credential installer lives inside another assembly, referenced by the website
using the Windsor source, the successful attempt to resolve occurs when the typeof(ICredentialCache).GetHashCode() is the same as what has been registered. For some reason when returning out of the installer the hashcode has changed for the type. Putting a debug line inside SimpleTypeEqualityComparer.GetHashCode(Type obj) shows that hashcodes are different for the same Type.
inspecting the container inside the debugger shows the ICredentialCache successfully installed.
Edit
Manage to move forward by manually registering installers, ie. not relying on the resolve<IwindsorInstaller>() and use container.install(new Installer(), ...). If i find out more I'll update the SO question.
This works fine for me:
public sealed class AppServiceFactory
{
...
public T Create<T>()
{
return (T)container.Resolve(typeof(T));
}
...
}
AppServiceFactory.Instance.Create<IYourService>();
The problem is caused by the InstallerHelper and how it goes about loading an assembly. This SO post pointed me in the right direction,
https://stackoverflow.com/a/6675227/564957
essentially the way the assembly was loaded was failing using Assembly.LoadFile(string fileName) was causing the problem, changing this to be Assembly.Load(string assemblyName) rectified the issue.
#Eric Lippert does a good job explaining
[when] loading an assembly by its path, and one via loading the same
assembly by its assembly name... reflection will
consider types from the two loadings of the same assembly to be
different types. Any assembly loaded from its path is considered to be
distinct from an assembly loaded by its assembly name.

Launching a JUnit test from an eclipse plugin using a custom JUnit runner implementation

I have written a custom JUnit runner that I want to become part of an eclipse plugin that will launch tests using this runner without having to apply the #RunWith annotation to the class. I have managed to get an additional item under the 'Run As' context menu, using the org.eclipse.debug.ui.launchShortcuts extension point. However, I am not sure how to invoke the test using my custom runner.
So I figured out a way to do what I wanted. However, it does seem a bit hacky. But, I thought that I would post the answer here in case someone else runs into the same problem.
First you have to register a junit kind like this:
<extension point="org.eclipse.jdt.junit.internal_testKinds">
<kind
id="my.junit.kind"
displayName="Your Kind Name"
finderClass="org.eclipse.jdt.internal.junit.launcher.JUnit4TestFinder"
loaderPluginId="org.eclipse.jdt.junit4.runtime"
loaderClass="your.test.loader.MyLoaderClass">
<runtimeClasspathEntry pluginId="org.eclipse.jdt.junit4.runtime" />
<runtimeClasspathEntry pluginId="org.eclipse.jdt.junit.core" />
<runtimeClasspathEntry pluginId="org.eclipse.jdt.junit.runtime"/>
</kind>
</extension>
In the xml you have to specify a custom implementation of org.eclipse.jdt.internal.junit.runner.ITestLoaderwhich in turn returns an implementation of org.eclipse.jdt.internal.junit.runner.ITestReference. The core part is the implementation of ITestReference, because this is where you create an instance of your custom JUnit runner.
public class MyTestReference extends JUnit4TestReference
{
public MyTestReference(final Class<?> p_clazz, String[] p_failureNames)
{
super(new Request()
{
#Override
public Runner getRunner()
{
return new MyCustomRunner(p_clazz);
}
}, p_failureNames);
}
...
}
Then finally you have to link this with a launch shortcut that sets the kind appropriately
public class MyJunitLaunchShortcut extends JUnitLaunchShortcut
{
#Override
protected ILaunchConfigurationWorkingCopy createLaunchConfiguration(IJavaElement p_element) throws CoreException
{
ILaunchConfigurationWorkingCopy config = super.createLaunchConfiguration(p_element);
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND, "my.junit.kind");
return config;
}
}
This does use a bunch of internal classes, so there is probably a better way. But this seems to work.