grzesiek-galezowski / AutoFixtureGenerator

An attempt to reimplement core features of a popular .NET anonymous value generator in Java
MIT License
17 stars 3 forks source link

Autofixture's ".with()" syntax #3

Open Pacane opened 10 years ago

Pacane commented 10 years ago

Hey! I thought of another feature of .Net AutoFixture that I'm really missing...

I don't know if it would be possible to use something similar .with() feature, without the lambdas (or maybe with them, in Java8, I don't know)

in Java 8

.create().with(x -> x.propertyName, value)

and I don't know about Java 7...

what do you think?

grzesiek-galezowski commented 10 years ago

Hi,

Actually, I think it would require not only support for lambdas, but also for expressions. If it was for lambdas only, we could just use an anonymous class instead - this was the way to achieve "labmdaness" in Java prior to version 8.

So the reason this kind of syntax works in .NET is that the lambda is really accepted as an Expression<Action<...>> or Expression<Func<...>>, not as an Action<...> or Func<...>. When we have an expression that consists of a single call, we can extract information about this call (e.g. method name) from the expression (this is how Moq works as well, byt the way).

There could be another way of dealing with this, like creating a runtime proxy and recording methods called (but this would leave out fields, since they're not polymorphic, and final methods). I wonder whether the new method reference syntax (ClassName::MethodName) could prove useful. Anyway, even if this was possible, it would leave out Java 7. So for now, I have no idea whether this is fully achievable in Java. Sure, we could use strings for method names in the with() calls, but that would scare off any potential user :-D.

By the way, there is a workaround, but with less syntactic sugar. One can always write:

MyType instance = fixture.create(new InstanceOf<MyType>() {});
instance.propertyName = value;

Anyway, if you're hungry for the feature and know a way to extract method/field name from lambda expression or anonymous class (or any other kind of representation that would make sense), then please let me know.

grzesiek-galezowski commented 10 years ago

Also, another point I find troubling is that Java lacks properties that .NET has. So even if we had a way to determine method call from lambda or anonymous class instance, it would not look so fluent for private fields that only have getters and setters:

fixture.build(new InstanceOf<MyObject>() {}).with(o -> o.setY(12));