For an embedded DSL I want classes to behave like a function. It seems easy for instances (https://www.dartlang.org/articles/emulating-functions/) but I couldn't make it happen for classes. I tried creating a static call a method but this didn't work either.
Is there a way or do I have to give the class another name and make Pconst a function, calling the constructor?
class Pconst {
final value;
Pconst(this.value);
static Pconst call(value) => new Pconst(value);
String toString() => "Pconst($value)";
}
void main() {
var test = Pconst(10);
// Breaking on exception: Class '_Type' has no instance method 'call'.
print("Hello, $test");
}
class TestA {
call(int a, int b) => a + b;
}
void main()
var TA = new TestA();
int integer = TA(3, 4);
print (integer);
}
The call() method is special, in that anyone who defines a call() method is presumed to dynamically emulate a function. This allows us to use instances of TestA as if they were functions that take two integer arguments.
I'd try something like this:
class _PConst{
final value;
_Pconst(this.value);
String toString() => "Pconst($value)";
}
PConst(value){
return new _PConst(value);
}
void main() {
var test = Pconst(10);
print("Hello, $test"); //should work ok
}
so your basically just hiding/wrapping your classes constructor behind a bog standard function.
Related
In Haxe, I created a class named MyClass like:
class MyClass {
var score: String;
public function new (score: Int) {
this.score = Std.string(score);
}
public function new (score: String) {
this.score = score;
}
}
I need multiple constructors but Haxe does not allow me to do. It throws this error from building phase:
*.hx:*: lines * : Duplicate constructor
The terminal process terminated with exit code: 1
How can I solve this problem?
This is known as method overloading, which is not supported by Haxe apart from externs (but might be in the future). There's multiple ways you could work around this.
A common workaround in the case of constructors would be to have a static "factory method" for the second constructor:
class MyClass {
var score:String;
public function new(score:String) {
this.score = score;
}
public static function fromInt(score:Int):MyClass {
return new MyClass(Std.string(score));
}
}
You could also have a single constructor that accepts both kinds of arguments:
class MyClass {
var score:String;
public function new(score:haxe.extern.EitherType<String, Int>) {
// technically there's no need for an if-else in this particular case, since there's
// no harm in calling `Std.string()` on something that's already a string
if (Std.is(score, String)) {
this.score = score;
} else {
this.score = Std.string(score);
}
}
}
However, I wouldn't recommend this approach, haxe.extern.EitherType is essentially Dynamic under the hood, which is bad for type safety and performance. Also, EitherType is technically only intended to be used on externs.
A more type-safe, but also slightly more verbose option would be haxe.ds.Either<String, Int>. Here you'd have to explicitly call the enum constructors: new MyClass(Left("100")) / new MyClass(Right(100)), and then use pattern matching to extract the value.
An abstract type that supports implicit conversions from String and Int might also be an option:
class Test {
static function main() {
var s1:Score = "100";
var s2:Score = 100;
}
}
abstract Score(String) from String {
#:from static function fromInt(i:Int):Score {
return Std.string(i);
}
}
Finally, there's also an experimental library that adds overloading support with macros, but I'm not sure if it supports constructors.
I recommend to use type parameter
class MyClass<T> {
var score:String;
public function new(score:T) {
this.score = Std.string(score);
}
}
You can also use type parameter at constructor
class MyClass {
var score:String;
public function new<T>(score:T) {
this.score = Std.string(score);
}
}
However, T used at constructor fails at runtime (CS and Java), it is not fixed yet (Haxe 4). Otherwise, you could do this
class MyClass {
var score:String;
#:generic public function new<#:const T>(score:T) {
this.score = Std.is(T, String) ? untyped score : Std.string(score);
}
}
which nicely produce code like this (CS)
__hx_this.score = ( (( T is string )) ? (score) : (global::Std.#string(score)) );
causing Std.string() to be called only if T is not a String.
Hej,
With a simple example as it is, you can just do something like that function new( ?s : String, ?n : Int ){} and Haxe will use the correct argument by type. But you'll be able to do new() and maybe you don't want.
I have read some post about it but nothing solved my problem. I have a class which is singleton and one method of this class is being called inside another class. I need to mock this method call.
Class SingletonClass
{
public static SingletonClass instance()
{
......
return instance;
}
public boolean methodToBeMocked(Object obj)
{
return false;
}
}
And the another class is :
Class A
{
Object doSomeStuff()
{
......
boolean result = SingletonClass.instance.methodToBeMocked();
}
}
And I am mocking the method methodToBeMocked in my test class. I have tried to use doReturn instead of thenReturn as it is suggested in other posts but it did not help.
My test class is :
Class TestClass{
Class A a = new A();
public void test()
{
SingletonClass singletonClass = mock(SingletonClass.class);
doReturn(true).when(singletonClass).methodToBeMocked(any());
a.doSomeStuff(); // here mocked method returns false
// but if I do this below it returns true !!!!
Object obj = new Object();
boolean result = singletonClass.mockedMethod(obj);
}
}
So why I am not getting true when a.doSomeStuff is called ? What is wrong here ?
For the benefit of others, I was using the following mock with the expectation it would not call someMock.someMethod(), unlike the when(someMock.someMethod()).doReturn("someString") usage.
Mockito.doReturn("someString").when(someMock).someMethod();
I could not understand why the real someMethod() was still being called. It turns out the method was specified as final. Mockito can't mock static or final methods.
The problem is the static method public static SingletonClass instance(). The standard mockito library does not support mocking of static methods. I seen two solutions.
You can rewrite small your code as:
Add new method getSingletonClassInstance() to be mocked in test
Class A {
Object doSomeStuff()
{
......
boolean result = getSingletonClassInstance();
}
SingletonClass getSingletonClassInstance(){
return SingletonClass.instance.methodToBeMocked();
}
}
use spy from mockito library to create an instance of Class A
import static org.mockito.Mockito.spy;
.....
Class TestClass{
public void test()
{
Class A a = spy(new A());
SingletonClass singletonClass = mock(SingletonClass.class);
doReturn(true).when(singletonClass).methodToBeMocked(any());
doReturn(singletonClass).when(a).getSingletonClassInstance();
a.doSomeStuff(); // here mocked method returns false
// but if I do this below it returns true !!!!
Object obj = new Object();
boolean result = singletonClass.mockedMethod(obj);
}
}
More information about the spy in mockito. Spy used real instance and invoke real method but provide a functionality to mock specific method. Don't worry about the others method they will continue to work with real implementation, only mocked method will be affected.
You can use power mockito to mock the public static SingletonClass
instance()
My colleague set up a Windsor TypedFactoryFacility in our project.
I'm new to Windsor and don't understand how it is implementing the the methods in the IServiceFactory interface we register as a factory. When I saw a Create method that takes a type parameter T and returns a T, I figured that it's probably calling the container's Resolve method under the covers.
I need an overload of Create that takes a Type as a parameter and returns an object. Since the container's Resolve method has both of these flavors:
T Resolve<T>(string key);
object Resolve(Type service);
I thought adding the overload of Create would work. Instead, it appears to be trying to resolve a System.Object instead of the Type I pass in.
Is there a way to make Windsor implement my Create method the way I want it to? I've poked around a bit with reflector, but can't figure it out.
Here is the registration:
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<IServiceFactory>()
.AsFactory()
.LifeStyle.Transient);
and the interface itself:
public interface IServiceFactory
{
//Original Create method that works
T Create<T>();
//The overload that I need that throws an exception
object Create(Type service)
void Release(object service);
}
Do you want to call something like serviceFactory.Create(typeof(IMyServce)) instead of serviceFactory.Create<IMyService>()?
Try using reflection in an extension method, like this
public static class ServiceFactoryExtensions
{
public static object Create(this IServiceFactory factory, Type serviceType)
{
return typeof(IServiceFactory).GetMethod("Create")
.MakeGenericMethod(serviceType).Invoke(factory, new object[]{});
}
}
EDIT:
This extension method does indeed work with a factory created by Castle Windsor.
Here's my original test code, which you can drop into Program.cs of a VS2010 console application, add a reference to Castle.Core and Castle.Windsor, and run. I used Castle.Windsor 2.5.4.
using System;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
namespace StackOverflow9198461
{
public static class ServiceFactoryExtensions
{
public static object Create(this IServiceFactory factory, Type serviceType)
{
return typeof(IServiceFactory).GetMethod("Create")
.MakeGenericMethod(serviceType)
.Invoke(factory, new object[] { });
}
}
class Program
{
static void Main()
{
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component
.For<IServiceFactory>()
.AsFactory());
container.Register(Component
.For<IMyService>()
.ImplementedBy<MyService>()
.LifeStyle.Singleton);
var factory = container.Resolve<IServiceFactory>();
var s1 = factory.Create<IMyService>();
var s2 = factory.Create(typeof(IMyService));
Console.WriteLine(s1.GetType().FullName);
Console.WriteLine(s2.GetType().FullName);
if (s1 == s2) Console.WriteLine("Success");
}
}
public interface IServiceFactory
{
//Original Create method that works
T Create<T>();
////The overload that I need that throws an exception
//object Create(Type service)
void Release(object service);
}
public class MyService : IMyService
{
}
public interface IMyService
{
}
}
I have to unit test some old code that wasn't designed to support unit testing (No DI). Is there a way to mock an object that is being initialized within a public method?
public int method() {
A a = new A(ar1, arg2); //How to mock this?
}
Thanks,
-Abidi
Another option is to refactor the code into
public int method() {
A a = createA(arg1,arg2);
}
A createA(int arg1, int arg2) {
return new A(arg1,arg2);
}
In your test method now you can use Mockito's spy and doAnswer functions to override createA on your test fixture with something along the lines of:
Foo foo = new Foo();
Foo spiedFoo = spy(foo); // a spied version when you can copy the behaviour
doAnswer(new Answer() {
#Override
public Object answer(InvocationOnMock inv) throws Throwable {
A a = mock(A.class);
return a;
}
}).when(mySpy).createA(anyInt(), anyInt());
If you have control over the code in question, you can refactor it and make the dependency public, for example by depending on some A-builder. This is probably the best solution, since it makes your class less dependent on A. [Forcing you to decouple your design is one of the main advantages of testing.]
I am able to get the signature and arguments from advised method calls, but I cannot figure out how to get the return values or exceptions. I'm kind of assuming that it can be done in some way using around and proceed.
You can use after() returning and after() throwing advices as in beginning of the following document. If you're using #AspectJ syntax please refer to #AfterReturning and #AfterThrowing annotations (you can find samples here).
You can also get return value using after returing advice.
package com.eos.poc.test;
public class AOPDemo {
public static void main(String[] args) {
AOPDemo demo = new AOPDemo();
String result= demo.append("Eclipse", " aspectJ");
}
public String append(String s1, String s2) {
System.out.println("Executing append method..");
return s1 + s2;
}
}
The defined aspect for getting return value:
public aspect DemoAspect {
pointcut callDemoAspectPointCut():
call(* com.eos.poc.test.AOPDemo.append(*,*));
after() returning(Object r) :callDemoAspectPointCut(){
System.out.println("Return value: "+r.toString()); // getting return value
}
Using an around() advice, you can get the return value of the intercepted method call by using proceed(). You can even change the value returned by the method if you want to.
For instance, suppose you have a method m() inside class MyClass:
public class MyClass {
int m() {
return 2;
}
}
Suppose you have the following aspect in its own .aj file:
public aspect mAspect {
pointcut mexec() : execution(* m(..));
int around() : mexec() {
// use proceed() to do the computation of the original method
int original_return_value = proceed();
// change the return value of m()
return original_return_value * 100;
}
}