How to deserialize Kotlin's lists in SpringBootTest - list

I'm setting up integration tests for a small Kotlin Spring Boot application. From what I have read, other people have had the same problems, but the suggested solutions do not work for me.
So, this is my test:
#Test
fun `Assert predefined checklists actually come back`(){
val assertedValues = listOf(
Checklist(listOf(Question("Wings"), Question("Whells"))),
Checklist(listOf(Question("Wings"), Question("Turbines"))))
val result = restTemplate
.withBasicAuth("username", "password")
.getForEntity<List<Checklist>>("/checklists")
assertThat(result.statusCode).isEqualTo(HttpStatus.OK)
assertThat(result.body).isNotNull
println(result.body)
for (checklist in result.body!!){
assertThat(assertedValues).contains(checklist)
}
}
As a recap, the problem surfacing here is that Jackson is unable to deserialize Kotlin's List class, so I get a ClassCastException:
java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class checklist.Checklist (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; checklist.Checklist is in unnamed module of loader 'app')
Neither Checklist nor Question are Kotlin data classes, just in case you want to ask.
What I found was this: Why kotlin jackson can't deserialize list
Bottom line: It may help to use Jackson's ObjectMapper in one of the following ways:
mapper.readValue(result, object : TypeReference<List<Checklist>>() {})
or, as in my case as I use the jackson-kotlin-module:
mapper.readValue<List<MyClass>>(result).
Sadly, this only leads to:
public final fun <T : Any!> readValue(p0: JsonParser!, p1: ResolvedType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: JsonParser!, p1: TypeReference<*>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: JsonParser!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: JsonParser!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: DataInput!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: DataInput!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: File!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: File!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: File!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: InputStream!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: InputStream!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: InputStream!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: Reader!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: Reader!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: Reader!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: URL!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: URL!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: URL!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: ByteArray!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: ByteArray!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: ByteArray!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: String!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: String!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: String!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
or respectivley, in the latter case:
public inline fun <reified T> ObjectMapper.readValue(jp: JsonParser): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: File): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: InputStream): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: Reader): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: URL): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: ByteArray): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(content: String): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
Therefore, I am outsmarted with my little Kotlin knowledge. For the sake of brevity I'd prefer not to explicitly parse every result in every test with the ObjectMapper, but I'd also be glad to make this work just in some way.

Related

How to mock and capture this combination of suspend functions

I have this class and interfaces:
class Class1(
private val interface1: Interface1,
private val interface2: Interface2,
private val interface3: Interface3,
private val coroutineScope: CoroutineScope
) {
fun start() {
coroutineScope.launch {
val string = interface1.execute { interface2.execute() }
interface3.execute(string)
}
}
}
interface Interface1 {
suspend fun execute(block: suspend () -> String): String
}
interface Interface2 {
suspend fun execute(): String
}
interface Interface3 {
fun execute(string: String)
}
When creating an actual implementation of this all works fine (interface1 is executed, then interface2 is executed, then interface3 is executed):
class MainActivity : AppCompatActivity(), Interface1, Interface2, Interface3 {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val c = Class1(this, this, this, GlobalScope)
c.start()
}
// implements interface1
override suspend fun execute(block: suspend () -> String): String {
Log.d("xyz1", "execute interface1")
return block()
}
// implements interface2
override suspend fun execute(): String {
Log.d("xyz1", "execute interface2")
return "someString"
}
// implements interface3
override fun execute(string: String) {
Log.d("xyz1", "execute interface3 $string")
}
}
Now I try to test Class1 with the following test:
#ExperimentalCoroutinesApi
class Class1Test {
private lateinit var interface1: Interface1
private lateinit var interface2: Interface2
private lateinit var interface3: Interface3
private lateinit var tested: Class1
#Before
fun setUp() {
interface1 = mock(Interface1::class.java)
interface2 = mock(Interface2::class.java)
interface3 = mock(Interface3::class.java)
tested = Class1(interface1, interface2, interface3, TestCoroutineScope())
}
#Test
fun `should execute on interface1 then interface2 and then interface3`() = runBlockingTest {
whenever(interface2.execute()).thenReturn("myString")
tested.start()
val captor = argumentCaptor<suspend () -> String>()
verify(interface1).execute(captor.capture())
captor.firstValue.invoke()
then(interface3).should().execute("myString")
}
}
But interface3.execute() is never called.
Debugging it, it seems like string is either not assigned or assigned too late (the lower breakpoint is reached, the upper one not):
Why is this test failing and how do I fix it?
PS: Changes to the production code are not an option.
PPS: If you want to play around with it, my little test project can be found here: https://github.com/fmweigl/SuspendTest

Unit Testing Service Layer in Spring Boot

I have a service layer (Code Below:)
#Service
public class EquityFeedsService {
#Autowired
private EquityFeedsRedisRepositoryImpl equityFeedsRedisRepositoryImpl;
public void save(EquityFeeds equityFeeds) {
logger.info("Inside the save method of EquityFeedsService.");
equityFeedsRedisRepositoryImpl.save(equityFeeds);
}
// other methods
}
Now I am trying to write a Unit Test case for the above method below:
#ExtendWith(SpringExtension.class)
#AutoConfigureMockMvc
public class EquityFeedsServiceTest {
private MockMvc mockMvc;
#InjectMocks
private EquityFeedsService equityFeedsService;
#Mock
private EquityFeedsRedisRepositoryImpl equityFeedsRedisRepositoryImpl;
#BeforeEach
public void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(equityFeedsService).build();
}
#Test
public void testSaveMethod() {
EquityFeeds equityFeeds = new EquityFeeds(423,"SAPEXTXN1", "GS");
when(equityFeedsRedisRepositoryImpl.save(any(EquityFeeds.class))).thenReturn(new EquityFeeds());
}
}
This code gives me the below Exception:
in line (any(EquityFeeds.class))
Required type:
EquityFeeds (This is my model class)
Provided:
Matcher <com.investmentbank.equityfeedsprocessingupdated.model.EquityFeeds> (This is the fully qualified path name of the mode class)
no instance(s) of type variable(s) T exist so that Matcher<T> conforms to EquityFeeds
and Exception :
Cannot resolve method 'thenReturn(com.investmentbank.equityfeedsprocessingupdated.model.EquityFeeds)'
What is wrong with my Unit Test Case? How do i solve this?

How to assign a param to a method in Reason

I have the following abstractFactory class:
class virtual virtualProductA = {
pub virtual methodA: string;
};
class virtual virtualProductB = {
pub virtual methodB: int;
};
class virtual abstractFactory = {
pub virtual createProductA : virtualProductA;
pub virtual createProductB : virtualProductB;
};
In particular, I would like to specify that the abstractFactory createProductA method has an optional param, that can be of any type.
Something along the lines of the following:
pub virtual createProductA (param?:any) : virtualProductA;
However, the above does not compile properly.
Any suggestions as to proper syntax is more than greatly appreciated. Thank you.
Disclaimer: I'm using OCaml. The Reason examples are translated using Try Reason.
I'm not sure I got your question right, but here are my thoughts on this.
If you want to give an argument to the constructor of your class virtualProductA, here the syntax.
OCaml
class virtual virtualProductA my_object = object
val value : 'a = my_object
method virtual methodA : string
end
Reason
class virtual virtualProductA my_object => {
as _;
val value: 'a = my_object;
pub virtual methodA: string;
};
In your abstract factory, the method createProductA now takes an argument and is polymorphic.
OCaml
class virtual abstractFactory = object
method virtual createProductA : 'a. 'a -> virtualProductA
method virtual createProductB : virtualProductB
end
Reason
class virtual abstractFactory = {
as _;
pub virtual createProductA: 'a. 'a => virtualProductA;
pub virtual createProductB: virtualProductB;
};
The type quantifier 'a. means "for all types 'a, ...". It is used to tell the compiler "This is not a type parameter, this is merely a polymorphic method".
On second thought, you will probably want to make virtualProductA generic, here's the syntax for that:
OCaml
class virtual ['a] virtualProductA my_object = object
val value : 'a = my_object
method value = value (* type 'a is inferred here, no need to over-annotate *)
method virtual methodA : string
end
Reason
class virtual virtualProductA 'a my_object => {
as _;
val value: 'a = my_object;
pub value = value; /* type 'a is inferred here, no need to over-annotate */
pub virtual methodA: string;
};

JAX-RS webservice testcase Injection of EntityManager sets NULL object in TestClass

I am beginner with JAX-RS webservice and its testcase.
My TestController class is as follows:
public class LotTypeMangementServiceTest {
private final String LOT_NAME = "lotName";
#Inject
private LotTypeManagementService lotTypeService;
#Test
private LotType testCreate() {
LotType newLotType = new LotType();
newLotType.setName(LOT_NAME);
//save
lotTypeService.createOrUpdate(newLotType);
Assert.assertNotNull(newLotType.getId());
return newLotType;
}
}
My LotTypeManagementService as follows:
#Stateless
public class LotTypeManagementService {
#PersistenceContext(unitName="primary")
private EntityManager em;
public void createOrUpdate(LotType lotType) {
if (lotType.getId() == null) { // Save New Label Type
em.persist(lotType);
} else { // Update Label Type
em.merge(lotType);
}
}
}
Now as you can see, LotTypeManagementService has EntityManager dependency.
In testclass, I've injected LotTypeManagementService. However, its dependency is not getting injected and hence I em object is NULL.
My persistence.xml file is as below:
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="primary">
<jta-data-source>java:jboss/datasources/lottype</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
My RestController is as below:
#RequestScoped
public class LotTypeResourceRESTService {
#Inject
private LotTypeManagementService lotTypeService;
}
I am using wildfly-9.0.1 server, java8, JAX-RS webservice, hibernate, jpa-2.1 and jUnit.
I found some solution on Stack Overflow like
Use #Inject or #Ejb
some change on persistance.xml <provider>org.hibernate.ejb.HibernatePersistence</provider>
em = (EntityManager) new nitialContext().lookup("java:/primary");
Like create dynamically container.
How can I do this correctly?

Unit testing callback based on Consumer functional interface

I'm trying to unit test code that runs as callback in a Consumer functional interface.
#Component
class SomeClass {
#Autowired
private SomeInteface toBeMockedDependency;
public method() {
toBeMockedDependency.doSomething(message -> {
// Logic under test goes here
// (implements java.util.function.Consumer interface)
...
});
}
}
#RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
#InjectMocks
private SomeClass someClass;
#Mock
private SomeInteface toBeMockedDependency;
#Test
public void testMethod() {
...
someClass.method();
...
}
}
Essentially I want to provide the tested code some tested "message" via "toBeMockedDependency".
How can the "toBeMockedDependency" be mocked to provide a predefined message?
Is it the right approach?
Don't try to make toBeMockedDependency automatically call your functional interface. Instead, use a #Captor to capture the anonymous functional interface, and then use your test to manually call it.
#RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
#InjectMocks
private SomeClass someClass;
#Mock
private SomeInteface toBeMockedDependency;
#Captor
private ArgumentCaptor<Consumer<Message>> messageConsumerCaptor;
#Test
public void testMethod() {
someClass.method();
verify(toBeMockedDependency).doSomething(messageConsumerCaptor.capture());
Consumer<Message> messageConsumer = messageConsumerCaptor.getValue();
// Now you have your message consumer, so you can test it all you want.
messageConsumer.accept(new Message(...));
assertEquals(...);
}
}