Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The ideal for me would be some strong static typing mode for the main code providing all the guarantees you want and some dynamic typing mode for the tests which lets you test everything well.

The main downside for me of the static typing is that it's close to impossible to provide a good testing experience, DSLs, mocks and spy objects kind of require some form of dynamic typing to be usable.



That’s exactly what the decade old Java for code and Groovy for tests is. Though it’s not used too often nowadays, mostly because Java is enough for testing for most people.


That is demonstrably false.

You can absolutely write DSLs, mocks, and spies in a statically-typed language.


Maybe that's possible in theory but I've never encountered a statically language where I consider the testing frameworks "good enough".


I'm not sure what to make of that. Maybe you just haven't bothered to look? You personally not knowing about something is a reflection of your own knowledge, and not of the state of the world.


No, I've look enough I think. Maybe those better frameworks do exist though indeed, but I have no proof of that. Usually they just have the bare minimum of assert checks and call it a day.

A testing framework should be able to mock and patch any class (or applicable) of the running instance of the program without modifying your code for example, tell me if a method was executed or not, intercepting all HTTP requests without changes, have complex assertion partially matching objects, factories, change the current time... I could add a lot more here.

All of that is necessary harder I think in a static typing environment.


> mock and patch any class (or applicable) of the running instance of the program without modifying your code

Why is it important for the sake of testing to be able to alter the runtime behaviour externally without changing the code? This is contrary to all TDD literature I've read which advises to make production code easy to test, e.g., by coding against interfaces. After all, something being hard to test is exactly the feedback you're looking for when doing Test Driven Design. If it's hard to test, it's probably too tightly-coupled.

> tell me if a method was executed or not

Spies are possible with e.g. the ReaderT pattern.

> intercepting all HTTP requests without changes

My earlier two points are applicable here too, although I'll add type classes as another viable solution.

> have complex assertion partially matching objects

Pretty easy with lenses or just making assertions against record field lookups.

> factories

I don't know what this means. I looked at several articles describing some kind of factory pattern in TDD — all of which were horrifically verbose — and all I can glean from that is we are talking about mocking some function which generates objects.

> change the current time

This is no different from mocking other system boundaries, which I have already addressed.

> I could add a lot more here

You're welcome to, and I imagine my suggested solutions will continue to follow a theme. I'm not sure you're here to have your mind changed though. It seems you've reached your conclusion already.


> Why is it important for the sake of testing to be able to alter the runtime behaviour externally without changing the code?

Because that's additional cruft that you don't want when reading your code. Yeah I get it, you can pass dozen of abstract classes to each constructor for each thing you are mocking (or equivalent if it's not a class-based language) that you replace if needed, the only problem with that is that it's inconvenient, prone to mistakes (you can forget some) and makes the code ugly (you don't want to read testing code on the main code).

I've done it in multiple static languages and at best it's a workaround that you should not have to deal with. I should add that any additional barrier to writing tests like this one also reduces the likelyhood that your app is well tested since some developers of your team might not bother going as far as that.

> Spies are possible with e.g. the ReaderT pattern.

After looking online, I'm not sure how that works, that does not looks very convenient for sure. Is that possible with that to say something like "the method X of class Y was executed 2 times with the parameters Z" without changing your code?

> I don't know what this means. I looked at several articles describing some kind of factory pattern in TDD — all of which were horrifically verbose — and all I can glean from that is we are talking about mocking some function which generates objects.

Something like https://github.com/thoughtbot/factory_bot

> This is no different from mocking other system boundaries, which I have already addressed.

Changing the time should also affect any sub dependency of your code which is calling to get the current time, not only your code.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: