How can Junit test classes detect classes defined in a kotlin file? - java

I have a Java gradle project in which i'm using a kotlin file to easily define pojo-like classes on one line. However, when i try to start a junit5 test I get a compile error stating that it can't detect any of the classes defined in the kotlin file. I have the kotlin plugin included in the gradle.build file. How do i get the test classes to detect the classes defined in the kotlin file?
Thank you

If you write JUnit5-tests with Gradle, be sure to have something like the following in place in your build.gradle-(or build.gradle.kts)-file, so that Gradle also knows that it should use the JUnit5-platform (compare also JUnit 5 User Guide - Build support - Gradle):
tasks.withType<Test> {
useJUnitPlatform()
}
Moreover also ensure that the annotation you use is the following:
org.junit.jupiter.api.Test
and not the one of JUnit4, i.e. org.junit.Test. If you have that one, you probably want to remove the junit4-dependency altogether.

Related

Pitest mutation testing execute over kotlin files only

I arrived to a legacy project where multiple files are developed in Java and many others in Kotlin. I have be able to configure Pitest to execute the mutation test and i have a correct report.
Now I would like to execute the mutation test only over the Kotlin files.
I tried to use the <targetClasses> but the param expresion is able to include certain packages, but I didn't discover a way to include certain types of files only.
I also tried to use the <excludedClasses> to add there a Java identificator that exclude this type of files, but again it doesn't work.
Do you know a way to use the targetClasses or the excludedClasses to let the kotlin files only in the scope of the Pitest execution?
Thank you in advance.
There is no built in way to limit mutation to only kotlin files. You would need to implement an mutation interceptor.
https://pitest.org/quickstart/advanced/
Or use the exclusions functionality provided by the arcmutate extentions to ignore files with a .java extension.
https://docs.arcmutate.com/docs/exclusions.html

SpringJUnit4ClassRunner isn't recognized as a type

My aplication uses Spring 4.3.1 and JUnit 4.12.
I have been trying test my methods with JUnit test cases.
I placed the #RunWith(SpringJUnit4ClassRunner.class) annotation in my test class, but eclipse complains "Class cannot be resolved to a type".
I read that this was enough for Eclipse to recognize SpringJUnit4ClassRunner, but isn't.
Is there Anything else remaining to do?
Try to:
Add spring-starter-test dependency through your configuration file & include relevant import statements in test files.
Delete local dependency repository & force new build to your application.
Adding the dependency spring-test the problem has been solved.
I didn't know there was need for this additional dependence, but someone told me here. Thank you.
I initially said that this measure was not enough because I had written the dependency version name wrongly and Maven was not finding the resource. But now it works!

Mock final class with Mockito 2

I'm removing Powermock from the project I'm currently working on, so I'm trying to rewrite some existing unitary test only with Mockito (mockito-core-2.2.28).
When I run the test, I have the following error:
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class com.ExternalpackagePath.Externalclass
Mockito cannot mock/spy because :
final class
I know that this question has already been asked (How to mock a final class with mockito, Mock objects calling final classes static methods with Mockito), but I didn't find the answer I'm looking for.
Here is an extract of my code :
public class MyClassToTest extends TestCase {
private MyClass myClass;
#Mock private Externalclass ext; // This class is final, I would like to mock it
#Override
protected void setUp() throws Exception {
MockitoAnnotations.initMocks(this); // <<<< The exception is thrown here
ext = Mockito.mock(Externalclass.class);
}
}
As mentioned in the Mockito documentation (https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2, §Mock the unmockable), I added the org.mockito.plugins.MockMaker file. This is the tree of my project :
project
src
com.packagePath.myPackage
myClass
test
com.packagePath.myPackage
myClassToTest
resources
mockito-extensions
org.mockito.plugins.MockMaker
I also tries to put the "resources" directory in "src", in a subdir called "test", but the result is still the same.
I thought that mocking a final was possible with Mockito v2. Does someone have an idea of what is missing here ?
Thanks!
Weird that your solution seems to work.
According to their documentation on Github it says.
Mocking of final classes and methods is an incubating, opt-in feature. It uses a combination of Java agent instrumentation and subclassing in order to enable mockability of these types. As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line:
mock-maker-inline
After you created this file, Mockito will automatically use this new engine and one can do :
final class FinalClass {
final String finalMethod() { return "something"; }
}
FinalClass concrete = new FinalClass();
FinalClass mock = mock(FinalClass.class);
given(mock.finalMethod()).willReturn("not anymore");
assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());
In subsequent milestones, the team will bring a programmatic way of using this feature. We will identify and provide support for all unmockable scenarios. Stay tuned and please let us know what you think of this feature!
My working structure now looks like this.
I couldn't get it working with the configuration file either; however, the Mockito team is so kind and also provides a pre-configured Mockito artifact that requires no configuration in the target project.
As a convenience, the Mockito team provides an artifact where this mock maker is preconfigured. Instead of using the mockito-core artifact, include the mockito-inline artifact in your project. Note that this artifact is likely to be discontinued once mocking of final classes and methods gets integrated into the default mock maker.
So, if you use Gradle and want to test your Kotlin code, just add this to your project's dependencies:
testCompile 'org.mockito:mockito-inline:2.8.9'
testCompile('com.nhaarman:mockito-kotlin:1.5.0') {
exclude group: 'org.jetbrains.kotlin'
exclude group: 'org.mockito'
}
Well, I found what's wrong here, it maybe useful for other people. My project tree is wrong, I put the org.mockito.plugins.MockMaker in a directory "mockito-extension" directly in "src". This is my tree now:
projet
src
com.packagePath.myPackage
myClass
mockito-extensions
org.mockito.plugins.MockMaker
test
com.packagePath.myPackage
myClassToTest
You seem to have had a classpath issue, just like I did.
Your previous setup would have also worked, but it seems like
project/test/resources
was not in your classpath.
I had the same issue when I tried to run this with IntelliJ. I simply marked the resources directory as a Test Resources Root and it worked fine. Praise the gods of Mockito!
I had the same issue that you described. For me, the solution was to create a file named org.mockito.plugins.MockMaker in /test/java/resources/mockito-extensions/ directory and write the following line: mock-maker-inline.
So MockMaker is actually the file extension (no txt, properties or any other extension needed).
I also encountered the same issue.
This worked for me: How to use the Mockito's inline mock maker: Option 2
Before Mockito can be used for mocking final classes and methods, it needs to be configured. Based on your screenshot of your project tree, it seems that the location of MockMaker file is incorrect.
Create (if the file still does not exist) or update MockMaker file in the path below
src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
... and add this line mock-maker-inline.
If you have multiple modules in project check out if they also have some references to Mockito. For me the problem was deprecated and unnecessary definition in some other small and forgotten library module:
testCompile 'org.mockito:mockito-all:1.10.19'
Removing this unnecessary declaration solved the problem for me
After following configuration instruction, I still wasn't able to get it working.
For me it was due to JDK I was using. After switching to a different one (different provider) the solution with org.mockito.plugins.MockMaker file worked.
I went from JDK with Hotswap agent (trava-jdk-11-dcevm / dcevm-11.0.11+1) to Eclipse adoptOpenJDK (temurin-11.0.14).
This solution worked for me:
Instead of
testCompile "org.mockito:mockito-android:2.9.0"
in the gradle file, replace it with
testCompile group: 'org.mockito', name: 'mockito-inline', version: '2.9.0'
and it would work.

How to run single Android local unit test using gradle 2.4. Test filtering is not supported

I'm using gradle to build my android project and am not able to run single local unit test. I have several test classes and one of them is MockServerTest and I only want to run test methods in this class.
I tried using gradle -Dtest.single=MockServerTest test but it turned out running all my tests, including these in other test classes.
I also tried gradle test --tests MockServerTest but an error occurred said
Test filtering is not supported for given version of junit. Please upgrade junit version to at least 4.6.
But I'm using junit 4.12 in my gradle file
testCompile 'junit:junit:4.12'
I'm using gradle 2.4 with com.android.tools.build:gradle:1.2.3.
Also, how can I run a single test method inside a single test class?
BTW, I'm able to run single test method inside Android Studio, by right clicking on the test method and select run targetTestMethod() from the menu. But how can I achieve this in the terminal? I guess Android Studio also trigger a certain command to do this. How can I see what that command is?
Figured it out myself. I have to run
gradle testDebug --tests com.my.package.TestClassName
There are two things to note here.
1. You have to use gradle testDebug or gradle testRelease instead of just gradle test. If you have build variant, you have to use gradle testVariantNameDebug or gradle testVariantNameRelease
2. You have to specify the whole qualified class name, means including the package name.
You can use Android Gradle plugin DSL to set up test tasks filters like this:
android {
testOptions {
unitTests.all {
it.testNameIncludePattern = "*.SomeTest"
}
}
}
You can find more information on testOptions here and filters here.
Have you tried running gradle test -Dtest.single=MockServerTest? More information can be found here.

How to make Gradle compile Groovy tests before Java tests

The Groovy plugin for Gradle claims that it "supports joint compilation, which allows to freely mix and match Groovy and Java code, with dependencies in both directions".
However, I don't think this applies to test code.
I have a Java 'sample' test in src/test/java... which uses a class which is located in src/test/groovy.
When trying to build with Gradle, I get an error like this:
SwingJavaFXSampleAppTestInJava.java:23: error: cannot find symbol
SwingJavaFXSampleAppTest swingJavaFx = new SwingJavaFXSampleAppTest();
Notice that SwingJavaFXSampleAppTest is a Groovy class that has not been compiled yet (in the Gradle output I can see that it did not run the compileTestGroovy before it tried compileTestJava because the former depends on the latter).
I am able to build this same project with Maven using the groovy-eclipse plugin.
Why does it not work in Gradle when it claims to support compilation in any order, and how can I make it work?
As explained in the Gradle User Guide, only code passed to GroovyCompile tasks is joint-compiled. So either you put both Java and Groovy code into src/main/groovy, or you reconfigure the source sets:
sourceSets.main.java.srcDirs = []
sourceSets.main.groovy.srcDirs = ["src/main/java", "src/main/groovy"]
For tests, replace all occurrences of main with test.
You should be able to move your java tests into src/test/groovy.

Categories

Resources