We have got a project from our university where they have created empty Java and Kotlin classes for us to add our code and some UnitTests to check if we have completed the assignments. I've been put in the Kotlin class and thus have to solve the problems in Kotlin and ignore Java. My problem now is that the UnitTests execute the Java code and not Kotlin.
For example:
Java Class:
package string;
public class Arrow {
public static String arrow(int length, boolean doubleEnded, boolean doubleLine) {
// TODO Implement the method
return "java";
}
}
Kotlin Class:
#file:JvmName("Arrow")
package string
// TODO Implement the function
fun arrow(length: Int, doubleEnded: Boolean, doubleLine: Boolean): String{
return "kotlin";
}
UnitTest and Result:
package string;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class ArrowTest {
static final int NBR_TESTS = 20;
#Test
void arrow0() {
Assertions.assertEquals("", Arrow.arrow(0, true, true));
Assertions.assertEquals("", Arrow.arrow(0, false, true));
Assertions.assertEquals("", Arrow.arrow(0, true, false));
Assertions.assertEquals("", Arrow.arrow(0, false, false));
}
}
org.opentest4j.AssertionFailedError:
Expected :
Actual :java
What do I have to do so that the UnitTests execute the Kotlin code and not Java?
They told us we should not change anything in the tests.
As #user3159253 commented changing the sourceDirectory did it for me.
I opened the module settings and removed Java as a source and added Kotlin.
Related
I've got a method in my Gradle plugin which declares a new "scratch" source set. I'm trying to convert this method from Groovy to Kotlin, but I cannot figure out how I'm meant to declare the new SourceSet using Kotlin.
class JavaConventionsPlugin : Plugin<Project> {
// ...
def scratchConfiguration(project) {
project.sourceSets {
scratch {
}
}
project.configurations {
// make scratch configurations include all normal dependencies automatically
scratchCompile.extendsFrom mainCompile
scratchRuntime.extendsFrom mainRuntime
scratchCompileOnly.extendsFrom compileOnly
scratchImplementation.extendsFrom implementation
scratchRuntimeOnly.extendsFrom runtimeOnly
}
project.dependencies {
// add dependency on main java code from scratch java code
scratchImplementation project.extensions.getByType(JavaPluginExtension).sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).output
}
}
}
Within the converted scratchConfiguration method, all of these seem to be unresolved references:
sourceSets
project.sourceSets
java.sourceSets
So what should the new SourceSet declaration look like?
They are unresolved because you are moving from a weakly typed/dynamic language (Groovy) to a strongly typed one (Kotlin). At its core, Gradle is written in plain Java. So, you need to make use of the Java APIs instead of the syntactic sugar that the Groovy DSL had provided.
Your snippet above would moreorless translate to the following:
import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
class ScratchGradlePlugin: Plugin<Project> {
override fun apply(project: Project) {
val sourceSets = project.extensions.getByType(SourceSetContainer::class.java)
val main = sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME)
sourceSets.register("scratch") {
it.compileClasspath.plus(main.get().output)
it.runtimeClasspath.plus(main.get().output)
}
val configurations = project.configurations
configurations.named("scratchImplementation") {
it.extendsFrom(configurations.named(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME).get())
}
configurations.named("scratchRuntimeOnly") {
it.extendsFrom(configurations.named(JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME).get())
}
}
}
I have omitted the project.dependencies {} part in your snippet since the sample above has scratch extend from main which is your main Java code.
Ref: https://docs.gradle.org/current/userguide/java_gradle_plugin.html#java_gradle_plugin
When running equalsverfier in quarkus dev mode, equalsverfier tests fail.
I tried to test a class with equalsverifier. This works in my IDE.
I tried to use it in quarkus dev mode (by running ./mvnw quarkus:dev), but then it fails with the following exception:
ERROR [io.qua.test] (Test runner thread) Test DingetjeTest#implementsEquals() failed
: java.lang.AssertionError: EqualsVerifier found a problem in class a.Dingetje.
-> Can not set final java.lang.String field a.Dingetje.text to a.Dingetje
For more information, go to: http://www.jqno.nl/equalsverifier/errormessages
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:308)
at a.DingetjeTest.implementsEquals(DingetjeTest.java:11)
Caused by: java.lang.IllegalArgumentException: Can not set final java.lang.String field a.Dingetje.text to a.Dingetje
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at java.base/jdk.internal.reflect.UnsafeQualifiedObjectFieldAccessorImpl.get(UnsafeQualifiedObjectFieldAccessorImpl.java:38)
at java.base/java.lang.reflect.Field.get(Field.java:418)
at nl.jqno.equalsverifier.internal.reflection.FieldModifier.lambda$copyTo$1(FieldModifier.java:79)
at nl.jqno.equalsverifier.internal.reflection.FieldModifier.lambda$change$3(FieldModifier.java:113)
at nl.jqno.equalsverifier.internal.util.Rethrow.lambda$rethrow$0(Rethrow.java:47)
at nl.jqno.equalsverifier.internal.util.Rethrow.rethrow(Rethrow.java:30)
at nl.jqno.equalsverifier.internal.util.Rethrow.rethrow(Rethrow.java:45)
at nl.jqno.equalsverifier.internal.util.Rethrow.rethrow(Rethrow.java:55)
at nl.jqno.equalsverifier.internal.reflection.FieldModifier.change(FieldModifier.java:113)
at nl.jqno.equalsverifier.internal.reflection.FieldModifier.copyTo(FieldModifier.java:79)
at nl.jqno.equalsverifier.internal.reflection.InPlaceObjectAccessor.copyInto(InPlaceObjectAccessor.java:43)
at nl.jqno.equalsverifier.internal.reflection.InPlaceObjectAccessor.copy(InPlaceObjectAccessor.java:24)
at nl.jqno.equalsverifier.internal.checkers.ExamplesChecker.checkSingle(ExamplesChecker.java:84)
at nl.jqno.equalsverifier.internal.checkers.ExamplesChecker.check(ExamplesChecker.java:47)
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verifyWithExamples(SingleTypeEqualsVerifierApi.java:413)
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.performVerification(SingleTypeEqualsVerifierApi.java:369)
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:304)
... 1 more
Here's the class under test:
package a;
import java.util.Objects;
public class Dingetje {
private final String text;
public Dingetje(String text) {
this.text = text;
}
#Override
public final boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Dingetje)) {
return false;
}
Dingetje other = (Dingetje) o;
return text.equals(other.text);
}
#Override
public final int hashCode() {
return Objects.hash(text);
}
}
And the test:
package a;
import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.jupiter.api.Test;
class DingetjeTest {
#Test
void implementsEquals() {
EqualsVerifier.forClass(Dingetje.class)
.withNonnullFields("text")
.verify();
}
}
What am I missing here?
EqualsVerifier uses Objenesis to create instances of classes, and it keeps the same reference of the objenesis object around for performance reasons. It caches all the objects it has created before, so that makes things quicker when you want to create the same object over and over again, which EqualsVerifier tends to do.
However, EqualsVerifier keeps a static reference to objenesis, which means that it lives as long as the JVM does. It turns out that the Quarkus test runner can re-run the same tests again and again, and it creates a new class loader each time. But part of the equality of java.lang.Class is that the classloader that created the class, must also be the same. So it couldn't retrieve these objects from its cache anymore and returnd instances with classloaders that are now different from the other objects created in the test, and this caused the exceptions that you saw.
In version 3.8 of EqualsVerifier (created as a result of this StackOverflow post), this issue can be avoided by adding #withResetCaches() like this:
EqualsVerifier.forClass(Dingetje.class)
.withResetCaches()
.withNonnullFields("text")
.verify();
That fixes the problem.
I am trying to translate the following reactive code into kotlin coroutines:
#GetMapping
fun getAllTodosMono(): Mono<CollectionModel<TodoItem>> =
repository
.findAll()
.collectList()
.flatMap { mkSelfLinkMono(it) }
private fun mkSelfLinkMono(list: List<TodoItem>): Mono<CollectionModel<TodoItem>> {
val method = methodOn(Controller::class.java).getAllTodosMono()
val selfLink = linkTo(method).withSelfRel().toMono()
return selfLink.map { CollectionModel.of(list, it) }
}
Coroutine Version:
#GetMapping
suspend fun getAllTodosCoroutine(): CollectionModel<TodoItem> =
repository
.findAll()
.collectList()
.awaitSingle()
.let { mkSelfLinkCoroutine(it) }
private suspend fun mkSelfLinkCoroutine(list: List<TodoItem>): CollectionModel<TodoItem> {
val method = methodOn(Controller::class.java).getAllTodosCoroutine()
val selfLink = linkTo(method).withSelfRel().toMono().awaitSingle()
return CollectionModel.of(list, selfLink)
}
However, I get a runtime error when trying to run the code.
java.lang.ClassCastException: class org.springframework.hateoas.server.core.LastInvocationAware$$EnhancerBySpringCGLIB$$d8fd0e7e cannot be cast to class org.springframework.hateoas.CollectionModel (org.springframework.hateoas.server.core.LastInvocationAware$$EnhancerBySpringCGLIB$$d8fd0e7e is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader #62b177e9; org.springframework.hateoas.CollectionModel is in unnamed module of loader 'app')
I suspect methodOn(...) does not support suspend functions. The only solution that actually works is to build the link by hand instead of using the linkTo(...) function:
private fun mkSelfLink(list: List<TodoItem>): CollectionModel<TodoItem> {
return Link
.of("/api/v1/todos")
.withSelfRel()
.let { CollectionModel.of(list, it) }
}
However, I lose the ability to link to existing endpoints in my REST controller and also the host that is automagically added to the link uri.
Am I missing something?
EDIT: Here is the link to my github repo: https://github.com/enolive/kotlin-coroutines/tree/master/todos-coroutini
If you paste the following code sample into the TodoController replacing the original getTodo(...) method, you can see the failure I described above.
private suspend fun Todo.withSelfLinkByBuilder(): EntityModel<Todo> {
val method = methodOn(Controller::class.java).getTodo(id!!)
val selfLink = linkTo(method).withSelfRel().toMono().awaitSingle()
return EntityModel.of(this, selfLink)
}
#GetMapping("{id}")
suspend fun getTodo(#PathVariable id: ObjectId) =
repository.findById(id)?.withSelfLinkByBuilder()
?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
Well, I found a solution, I don't know if is it a satisfactory one, but it works, none of the less.
By simple chaining the function calls together the runtime appears to work as intended:
private suspend fun mkSelfLinkCoroutine(list: List<TodoItem>): CollectionModel<TodoItem> {
val selfLink = linkTo(methodOn(Controller::class.java)
.getAllTodosCoroutine())
.withSelfRel()
.toMono()
.awaitSingle()
return CollectionModel.of(list, selfLink)
}
This is really strange, but it is what it is.
You probably forgot to add coroutines to your project. Add these dependencies to your gradle file:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
I am trying to include Room persistence library to my android project. I am using gradle dependency android.arch.persistence.room:runtime:1.1.1 library, not the androidx
I have tried changing the version to 1.1.0 & 1.1.0-beta2 but getting same error.
Gradle dependencies for Room:
// Room components
implementation "android.arch.persistence.room:runtime:$rootProject.roomVersion"
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion"
androidTestImplementation "android.arch.persistence.room:testing:$rootProject.roomVersion"
Here $rootProject.roomVersion value is 1.1.1
Support library version:
`implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'`
The AppDatabase class:
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.content.Context;
import com.samcaraschools.userlistapp.module.User;
#Database(entities = {User.class},version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
public static AppDatabase mDatabase;
public abstract UserDao userDao();
public static AppDatabase getAppDatabase(Context context) {
if (mDatabase == null) {
synchronized (AppDatabase.class) {
if (mDatabase == null) {
mDatabase = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, "word_database")
// Wipes and rebuilds instead of migrating
// if no Migration object.
// Migration is not part of this practical.
.fallbackToDestructiveMigration()
.build();
}
}
}
return mDatabase;
}
}
With the above code in place I am getting the following error:
error: incompatible types: SupportSQLiteDatabase cannot be converted to AppDatabase
What is wrong with my code?
The error is because of the name of the object of class AppDatabase. Rename it to any object name than mDatabase, then it will function properly.
If you check your AppDatabase_Impl.java, you will notice that mDatabase has error. This is because SupportSQLiteDatabase.java has object name mDatabase which gets override by the object name placed in AppDatabase.
These libraries are loaded:
JUnit 5.3.2
JaCoCo 0.8.2
Mockito 2.10.0
Only element "static {...}" appears with 100% coverage. All the rest is at 0%:
The unit test class has annotations #ExtendWith(SpringExtension.class) and #AutoConfigureMockMvc. The service is injected with #Mock.
doReturn(actual).when(service).get(param);
when(service.get(param)).thenReturn(actual);
expected = service.get(param);
verify(service, times(1)).get(param);
assertEquals(expected, actual);
assertEquals(actual, expected);
My ServiceImpl class is red when I click any method. It extends an abstract class. Jackson's ObjectMapper is red, and also the entire lines within the methods. For example:
public CustomReturnObject get(final CustomParamObject paramObject) {
try {
return retryTemplate.execute(status -> {
String json = repository.get(paramObject);
CustomReturnObject returnObject = json2CustomObject(json, paramObject);
if (returnObject == null) {
returnObject = new CustomReturnObject();
returnObject.setId(paramObject.getId());
}
return returnObject;
});
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
return null;
}
}
Similarly to https://stackoverflow.com/a/46614216/244993 let's put aside Spring, because there is IMO clearly something wrong with your expectations/understanding about core thing here - mocking.
By
doReturn(actual).when(service).get(param);
expected = service.get(param);
verify(service, times(1)).get(param);
assertEquals(expected, actual);
you are not testing get method, you are testing something that always returns actual, no matter what is actually written in get, because in this case it is not executed.
Here is complete example as a proof:
src/main/java/hello/GreetingService.java:
package hello;
class GreetingService {
Object get(Object param) {
throw new UnsupportedOperationException();
}
}
src/test/java/hello/GreetingServiceTest.java:
package hello;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
#ExtendWith(MockitoExtension.class)
public class GreetingServiceTest {
#Mock
public GreetingService service;
#Test
void test() {
Object param = new Object();
Object actual = new Object();
doReturn(actual).when(service).get(param);
Object expected = service.get(param);
verify(service, Mockito.times(1)).get(param);
assertEquals(expected, actual);
}
}
build.gradle :
apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile 'org.mockito:mockito-junit-jupiter:2.23.4'
}
Real method get throws UnsupportedOperationException, however above test succeeds, so real method was not executed. As another way to proof that get not executed: put a breakpoint into it and execute test in debug mode from IDE - breakpoint won't be reached.
Coverage shows what was really executed and hence absolutely correct that it is zero for methods that are not executed.