I have definiction of the function
abstract class AbstractDao<T>(private val dataStore: KotlinEntityDataStore<Persistable>): Dao<T> where T: Persistable
and I need to get KClass from type T. It is possible in Kotlin ?
This cannot be done due to type erasure. But you could provide a factory method with reified type that delegates to a constructor accepting the KClass. Here's a simplified example:
class WithReifiedType<T> constructor(val kc: KClass<*>) {
companion object {
inline fun <reified T> getInstance(): WithReifiedType<T> {
println("Here's your KClass: ${T::class}")
return WithReifiedType(T::class)
}
}
}
//called like this
WithReifiedType.getInstance<String>()
It's also acceptable to create a top-level function (as an alternative to companion-embedded factory) looking like a constructor on the caller site.
inline fun <reified T> WithReifiedType(): WithReifiedType<T> {
println("Here's your KClass: ${T::class}")
return WithReifiedType(T::class)
}
//called like this
WithReifiedType<String>()
Related
I have a Corda flow written in kotlin which takes lambda as an argument:
class ApproveFlow(val arg1: String, val arg2: (Amount<Currency>) -> Amount<Currency>) : FlowLogic<SignedTransaction>()
If I try to invoke the flow over RPC as shown below, Kryo throws an exception:
nodeBProxy.startFlow(::ApproveFlow, "abc", (BasicCalculator()::computeValue))
computeValue function is defined as below:
#CordaSerializable
interface Calculator {
fun computeValue(purchasePrice: Amount<Currency>): Amount<Currency>
}
#CordaSerializable
class BasicCalculator : Calculator {
override fun computeValue(purchasePrice: Amount<Currency>): Amount<Currency>
{ ...
...
return 100.POUNDS
}
}
Exception:
is not annotated or on the whitelist, so cannot be used in serialization corda
Passing a function as a parameter to a flow is probably a bit ambitious. The node needs to evaluate it, after all, and checkpoint it so it can be evaluated later. If you really want to do this you can like so:
val lambda = #CordaSerializable Runnable { whatever() }
or
val lambda = #CordaSerializable fun() { whatever() }
.... but I'd suggest keeping it simple and just passing into plain old data objects. Yes, object serialization is powerful. But with great power comes great responsibility!
Given:
// #flow
declare interface IFoo {
test();
}
class Foo implements IFoo {
test () {
console.log('in test');
}
}
if i had a function:
// some function
async function demo (argA: string, argB: INSTANCE_OF_Foo) { ... }
how can i tell flow that argB is "instance of class that implements IFoo"? in other words if the usage of function demo had to be like
const foo: IFoo = new Foo();
demo('bla' foo);
How can i ensure what get's passed to demo is instance of a class that implements IFoo?
type script interface is ignored at runtime, it is only used at compile time for type checking. So there is no way you can check whether the Foo is implemented with IFoo.
But you can check whether foo is an instance of Foo class.
So it depends on what you seek: you can either ensure the argument implements IFoo:
async function demo (argA: string, argB: IFoo)
, or the argument is an instance of the class Foo:
async function demo (argA: string, argB: Foo)
But I must say, it's not really clear why you need to require an instance instead of an interface (which I think is the way to go here).
You can play with this easily at flow.org/try.
Hope this helps!
When I have a class that has a companion object, is it possible to set a property in this companion object using reflection? I can do it with normal properties, but fail on companion objects:
import kotlin.reflect.KMutableProperty
import kotlin.reflect.full.companionObject
import kotlin.reflect.full.memberProperties
class WithProperty {
lateinit var prop: String
companion object {
lateinit var companionProp: String
}
fun test() = "$companionProp $prop"
}
fun main(args: Array<String>) {
val obj = WithProperty()
val prop = obj::class.memberProperties.filter { it.name == "prop" }.first()
if (prop is KMutableProperty<*>) {
prop.setter.call(obj, "world")
}
val companion = obj::class.companionObject
if (companion != null) {
val companionProp = companion.memberProperties.filter { it.name == "companionProp" }.first()
if (companionProp is KMutableProperty<*>) {
companionProp.setter.call(companionProp, "hello") // <-- what must go here as first argument?
}
}
println(obj.test())
}
Calling the setter for the normal property works as it should, but when I call companionProp.setter.call(companionProp, "hello") I get
Exception in thread "main" java.lang.IllegalArgumentException: object is not an instance of declaring class
What do I have to pass as first argument to call() to succeed?
Edit: I wrote companionPropas first argument, but that definitely is wrong, I actually tried with the companion object, but that is not working as well.
object is not an instance of declaring class
Just as in Java, you need to pass the object itself as the first parameter when calling reflective methods.
The first parameter to call should be the companion object, as that is the object whose property you are trying to modify.
You are passing the companion's class object instead of the companion object itself.
A companion object is accessible either via ClassName.Companion, or when using further reflection, through KClass#companionObjectInstance.
companionProp.setter.call(WithProperty.Companion, "hello")
companionProp.setter.call(obj::class.companionObjectInstance, "hello")
companionProp.setter.call(WithProperty::class.companionObjectInstance, "hello")
When run, both variants print hello world as intended.
Keep in mind that Foo.Companion will result in a compile error if the companion object does not exist while the reflective variant will return null instead.
the first argument is the instance of the declaring class.
you pass a KProperty instance companionProp rather than a companion object instance. However, you can using KClass.companionObjectInstance to obtain the compantion instance. for example:
//a non-static property having a receiver, so it should be a KMutableProperty1 here
// v
if (companionProp is KMutableProperty1<*, *>) {
// get the companion object instance ---v
companionProp.setter.call(obj::class.companionObjectInstance, "hello")
}
You can solve the same problem using java reflection.
Companion class:
class Example {
companion object {
val EXAMPLE_VALUE = "initial"
}
}
Update a property using java reflection:
val field = Example::class.java.getDeclaredField("EXAMPLE_VALUE")
field.isAccessible = true
field.set(null, "replaced")
Tested with Kotlin 1.5.30 on Android 12:
Log.d("test-companion", Example.EXAMPLE_VALUE) // outputs "replaced"
WARNING: I'm not sure if java reflection is reliable for this case. It assumes some implementation details of Kotlin complier which could change in a future version. But the solution should be fine for a quick workaround. I used it to verify a bug fix on customer side before the next release of my library.
I need an object that makes instances of other objects. I want the ability to pass in the class of the objects being created, but they all need to have the same type, and it would be great if they could all start out with the same values:
class Cloner{
BaseType prototype;
BaseType getAnother(){
BaseType newthing = prototype.clone(); //but there's no clone() in Dart
newthing.callsomeBaseTypeMethod();
return newthing;
}
}
So, prototype could be set to any object that is of type BaseClass, even if it's something whose class is a subclass of BaseClass. I'm sure there's a way to do this with the mirrors library, but I just wanted to make sure I'm not missing some obvious built-in factory way to do it.
I could see how this could be set up with a generic: Cloner<T>, but then there's no way that we can make sure T is a subtype of BaseType at compile-time, right?
To get you started, you can create a small "constructor" function that returns new instances. Try this:
typedef BaseType Builder();
class Cloner {
Builder builder;
Cloner(Builder builder);
BaseType getAnother() {
BaseType newthing = builder();
newthing.callsomeBaseTypeMethod();
return newthing;
}
}
main() {
var cloner = new Cloner(() => new BaseType());
var thing = cloner.getAnother();
}
In the above code, we create a typedef to define a function that returns a BaseType.
I am modifiying a class method which formats some input paramater dates which are subsequently used as params in a method call into the base class (which lives in another assembly).
I want to verify that the dates i pass in to my method are in the correct format when they are passed to the base class method so i would like to Moq the base class method call. Is this possible with Moq?
As of 2013 with latest Moq you can. Here is an example
public class ViewModelBase
{
public virtual bool IsValid(DateTime date)
{
//some complex shared stuff here
}
}
public class MyViewModel : ViewModelBase
{
public void Save(DateTime date)
{
if (IsValid(date))
{
//do something here
}
}
}
public void MyTest()
{
//arrange
var mockMyViewModel = new Mock<MyViewModel>(){CallBase = true};
mockMyViewModel.Setup(x => x.IsValid(It.IsAny<DateTime>())).Returns(true);
//act
mockMyViewModel.Object.Save();
//assert
//do your assertions here
}
If I understand your question correctly, you have a class A defined in some other assembly, and then an class B implemented more or less like this:
public class B : A
{
public override MyMethod(object input)
{
// Do something
base.MyMethod(input);
}
}
And now you want to verify that base.MyMethod is called?
I don't see how you can do this with a dynamic mock library. All dynamic mock libraries (with the exception of TypeMock) work by dynamically emitting classes that derive from the type in question.
In your case, you can't very well ask Moq to derive from A, since you want to test B.
This means that you must ask Moq to give you a Mock<B>. However, this means that the emitted type derives from B, and while it can override MyMethod (which is still virtual) and call its base (B.MyMethod), it has no way of getting to the original class and verify that B calls base.MyMethod.
Imagine that you have to write a class (C) that derives from B. While you can override MyMethod, there's no way you can verify that B calls A:
public class C : B
{
public override MyMethod(object input)
{
// How to verify that base calls its base?
// base in this context means B, not A
}
}
Again with the possible exception of TypeMock, dynamic mock libraries cannot do anything that you cannot do manually.
However, I would assume that calling the base method you are trying to verify has some observable side effect, so if possible, can you use state-based testing instead of behaviour-based testing to verify the outcome of calling the method?
In any case, state-based testing ought to be your default approach in most cases.
Agree with Mark, it's not possible using Moq.
Depending on your situation you may consider swithcing from inheritance to composition. Then you'll be able to mock the dependency and verify your method. Of course in some cases it just might not worth it.
wrap the base class method in a method and setup that method
e.g.
public class B : A
{
public virtual BaseMyMethod(object input)
{
// Do something
base.MyMethod(input);
}
public override MyMethod(object input)
{
// Do something
BaseMyMethod(input);
}
}
and now Setup the BaseMyMethod
It is quite possible mocking base class. But you will have to modify target class.
For ex. DerivedClass extends BaseClass.
BaseClass has methods MethodA(), MethodB(), MethodC()...
The DerivedClass has this method:
void MyMethod() {
this.MethodA();
this.MethodB();
this.MethodC();
}
You want to mock base class in order to validate that all MethodA(), MethodB(), MethodC() are being called inside MyMethod().
You have to create a field in the DerivedClass:
class DerivedClass {
private BaseClass self = this;
...
}
And also You have to modify the MyMethod():
void MyMethod() {
self.MethodA();
self.MethodB();
self.MethodC();
}
Also add a method, which can inject the this.self field with Mock object
public void setMock(BaseClass mock) {
this.self = mock;
}
Now you can mock:
DerivedClass target = new DerivedClass ();
BaseClass mock = new Mock(typeof(BaseClass));
target.setMock(mock);
target.MyMethod();
mock.verify(MethodA);
mock.verify(MethodB);
mock.verify(MethodC);
Using this technic, you can also mock nested method calls.
I found this solution - ugly but it could work.
var real = new SubCoreClass();
var mock = new Mock<SubCoreClass>();
mock.CallBase = true;
var obj = mock.Object;
mock
.Setup(c => c.Execute())
.Callback(() =>
{
obj.CallBaseMember(typeof(Action), real, "Execute");
Console.WriteLine(obj.GetHashCode());
}
);
public static Delegate CreateBaseCallDelegate(object injectedInstance, Type templateDelegate, object instanceOfBase, string methodName)
{
var deleg = Delegate.CreateDelegate(templateDelegate, instanceOfBase, methodName);
deleg.GetType().BaseType.BaseType.GetField("_target", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(deleg, injectedInstance);
return deleg;
}
public static object CallBaseMember(this object injectedInstance, Type templateDelegate, object instanceOfBase, string methodName, params object[] arguments)
{
return CreateBaseCallDelegate(injectedInstance, templateDelegate, instanceOfBase, methodName).DynamicInvoke(arguments);
}