juxt

dominicm 2020-04-17T06:30:41.054700Z

Maybe it's not necessary to mock the http client, you don't need to test the library. Just swap the middleware out when testing.

2020-04-17T07:22:13.055100Z

I’m building my own framework 😎

2020-04-17T07:22:32.055500Z

Not for APIs, I’ll leave that to Apex, but for web apps

2020-04-17T07:22:58.056100Z

And I would like to use the OpenId code in other places too. I think it’s just better to do it this way

2020-04-17T07:24:43.057300Z

I’ll not force my ideas upon others, but I’ll be forced to create my own library as this style of development requires and all-in approach

dominicm 2020-04-17T07:42:18.059600Z

I'm not sure what property you're really testing by mocking http though :thinking_face:

2020-04-17T07:42:47.060300Z

Yeah long story 🙂

2020-04-17T07:46:02.063400Z

If I’m integrating an open Id library into my application, I need to deal with this in my tests. My tests are setup to mock http by using protocols. So I need the library to satisfy these protocols. Swapping middleware is one way, but I think there are better ways

2020-04-17T07:46:32.063700Z

Also, where is the openid part in Apex tested?

dominicm 2020-04-17T07:48:22.066500Z

I mean from a higher level. There's not much point faking openid interactions when you can bypass them for the purposes of testing. The only reason to mock openid is to ensure the library does what it says. But I doubt you test all your libraries this way.

2020-04-17T07:48:43.066700Z

You might be wrong 🙂

2020-04-17T07:48:56.067Z

Anyway, i’m not here to convince anyone

2020-04-17T07:49:32.068400Z

Do you know the VCR approach in ruby?

dominicm 2020-04-17T07:49:38.068600Z

Haha. I'm now terrified at the idea of you importing all your dependencies' test folders

dominicm 2020-04-17T07:49:50.069100Z

I don't, I'm guessing it's like clj-vcr though

2020-04-17T07:50:45.070Z

Haha no I mean, i’m not assuming the libraries are well-tested. So i’m using integration tests to verify it works the way i think it works

2020-04-17T07:51:05.070600Z

And I try to make this practical by having a well-tested http layer that runs in memory

2020-04-17T07:51:17.070800Z

This includes dns lookups

2020-04-17T07:51:31.071200Z

I’m still missing a VCR solution, but I’m getting there

dominicm 2020-04-17T07:51:46.071700Z

I wonder if a jvm agent would work for that.

2020-04-17T07:52:03.072Z

Would that work in parallel on the same JVM?

2020-04-17T07:52:25.072400Z

I have never tried it. It sounds scary 🙂

dominicm 2020-04-17T07:53:50.073200Z

If you were really crazy you'd use a ld preload 😀 that works on any executable.

dominicm 2020-04-17T07:54:21.074Z

Something like sockify pointing at a custom socks5 server would give you total assurance.

2020-04-17T07:54:46.074400Z

You think i’m not serious I guess 🙂

2020-04-17T07:54:57.074700Z

This guy understands me 🙂 https://www.youtube.com/watch?v=ikLFUmY70u8&t=1945s

dominicm 2020-04-17T07:55:59.075800Z

No, I'm not teasing. I actually think sockify is a good idea.

2020-04-17T07:56:29.076700Z

Ok I don’t know enough about it. Is it practical though?

dominicm 2020-04-17T07:56:48.077300Z

I'm thinking out loud: what other ways you could capture external traffic and transform it.

2020-04-17T07:57:51.078700Z

I don’t know, i’ve solved it by using Clojure protocols

dominicm 2020-04-17T07:58:13.079600Z

Like, using an LD preload would mean this part of your tests needs to run in a separate JVM. But it would give you a high assurance that nothing is happening without you knowing.

2020-04-17T07:58:57.080200Z

I have no idea what LD preload is

2020-04-17T07:59:31.080900Z

For me it works to solve it at the Clojure level, that’s also my preference. The thing that I deeply understand

dominicm 2020-04-17T08:00:23.082100Z

It's a way to override the function calls being made to the operating system. Eg fstat, fopen, etc

2020-04-17T08:00:42.082800Z

Ah yeah that would be super useful for lowlevel programming

2020-04-17T08:01:14.083800Z

If you stay at the http layer, things are still simple enough to stay away 😅

dominicm 2020-04-17T08:01:28.084300Z

You could also go at the JVM level to set a socks proxy, that would allow you to work at the http layer.

dominicm 2020-04-17T08:02:24.086100Z

Then you write a small socks proxy which calls you to say there's a http request, what do you want to do?

2020-04-17T08:02:32.086500Z

Why are you telling me to swap middleware and now you are telling me to go to the operating system? :rolling_on_the_floor_laughing:

dominicm 2020-04-17T08:03:07.087500Z

Going lower lets you have very holistic control I guess :). Socks is probably the best layer in terms of minimum work & broad coverage.

2020-04-17T08:03:58.088100Z

Might be true hehe. But is something I’m not comfortable with (yet). I’m fine in this position

2020-04-17T08:04:14.088500Z

I would love to see someone explore this field for me though! I’m not ready yet

2020-04-17T08:04:57.089700Z

Btw I feel I have holistic control in my current setup

dominicm 2020-04-17T08:06:05.091200Z

I'm exploring this (in words) because I think that adding flags for http clients adds complexity. Given how uncommon the kind of testing you're aiming to do is, I'm trying to think of other ways it could be achieved.

2020-04-17T08:06:36.092Z

Fair enough

2020-04-17T08:06:47.092500Z

I don’t understand why it’s uncommon though

2020-04-17T08:06:51.092800Z

In ruby it wasn’t

dominicm 2020-04-17T08:06:52.092900Z

Well, it's okay until you use a java library which doesn't support your choice of clojure http client? 😝

2020-04-17T08:08:08.093200Z

Yeah that’s sucks, I’ll have to use another library

2020-04-17T08:08:28.093800Z

There are a few cases where I have to surrender

dominicm 2020-04-17T08:08:30.094Z

Yeah, that's an interesting question. It might have something to do with global variables perhaps, or maybe just culture. Dunno.

2020-04-17T08:09:22.094800Z

I prefer to go the painful route of rewriting something or searching for libraries that fit, than to adapt my way of building applications

2020-04-17T08:09:27.095Z

I can sleep at night 🙂

2020-04-17T08:09:57.095500Z

I hope I can convince enough people at some point

dominicm 2020-04-17T08:09:59.095600Z

One reason I think VCR is not more popular in Clojure is that Clojure (and other functional languages) work on composition rather than hierarchy.

2020-04-17T08:10:43.096200Z

If you build an integration with an external API, what are other ways to properly test this?

2020-04-17T08:11:00.096500Z

Does it matter what language you use?

2020-04-17T08:12:05.097500Z

I see only one option: scheduled full integration tests + VCR-ed integration test to distinquish internal failures from external failures

2020-04-17T08:13:16.098400Z

So let’s we would be building something like let say an openid connector, how can we test this reliably? 😅

dominicm 2020-04-17T08:15:06.098800Z

I'd probably test the functions which process the request/result.

dominicm 2020-04-17T08:15:23.099Z

But these are internal tests. Internal to the library.

2020-04-17T08:16:20.099800Z

In my experience there are moments when external API’s suddenly change. This moment you want to detect as an external change

2020-04-17T08:16:44.100300Z

First problem is detecting is: schedule full integration tests

2020-04-17T08:17:04.100800Z

Second problem is knowing that it’s not your code: VCR-ed integration test

2020-04-17T08:17:37.101400Z

You could do it with manually processing the request/result, but there is a lot of labour there

2020-04-17T08:18:02.101800Z

I still don’t use a VCR approach in Clojure, but I strongly miss it

dominicm 2020-04-17T08:19:16.101900Z

That's interesting. These aren't exactly tests you'd run at check-in then?

dominicm 2020-04-17T08:19:25.102Z

You'd run them in production? - and monitor the results conform to some spec at all times?

2020-04-17T08:20:27.103Z

You can run VCR tests anytime. The full integrations tests are too slow and once a day on CI should be fine

2020-04-17T08:21:18.104Z

A long time ago I was working on a service that had integration with Twitter, Facebook etc. We would run full integration tests with real accounts

2020-04-17T08:21:57.104800Z

It wasn’t perfect, so we did VCR tests locally and full integrations tests on CI

2020-04-17T08:22:05.105Z

Scheduled would have been better

2020-04-17T08:22:19.105400Z

We had many broken builds due to timeouts of the APIs

dominicm 2020-04-17T08:23:56.105500Z

Stepping back. Unless you updated your OpenID library / changed your config, you know the failure is external? e.g. the integration tests were fine for 7 days since the last commit and then failed.

2020-04-17T08:24:56.105700Z

Yeah true

2020-04-17T08:25:29.106400Z

In a business application, it is very likely that you had many updates in those 7 days

2020-04-17T08:26:17.107200Z

I guess the question is whether you are actually working on the openid code or not

2020-04-17T08:26:44.107700Z

If the library underneath has these tests, than you don’t have to do it as well

2020-04-17T08:27:05.108100Z

But I have never seen this in practise

2020-04-17T08:27:21.108600Z

So if your business depends on it, you probably want to do it this way

2020-04-17T08:27:50.108900Z

Thanks for challenging me 🙂

2020-04-17T08:28:01.109300Z

Need to get some work done now

dominicm 2020-04-17T08:28:18.109400Z

Honestly - it's all for me 😀 I want to learn about this testing approach I don't entirely understand!

2020-04-17T08:28:35.109700Z

Ok let me finish this framework and you will see it

2020-04-17T08:29:19.110600Z

And also watch that presentation. He has similar ideas

2020-04-17T08:29:50.111300Z

In an application I try to make everything deterministic. That means: random numbers, http, time and anything that is related

2020-04-17T08:30:08.111600Z

It makes live much easier

2020-04-17T08:30:17.111900Z

(and your tests faster)

2020-04-17T20:58:52.112700Z

hello, is this an appropriate channel to inquire about the tick time lib?

dominicm 2020-04-17T20:59:47.113Z

Yes

2020-04-17T21:01:20.114700Z

cool, thanks. I am writing specs for some data, and want to validate that some fields are some tick data types, I didn't see any functions in the lib, so I am making my own like so:

(defn date? [d] (= (type d) (type (t/date))))
(comment (date? (t/date)))

(defn date-time? [d] (= (type d) (type (t/date-time))))
just wanted to see if there is some other way to check for these provided in tick

dominicm 2020-04-17T21:07:08.115Z

Right though. You might want to use instance?

2020-04-17T21:09:11.115300Z

i don't believe the classes are exposed via the api

2020-04-17T21:12:25.115900Z

ah, i see what you mean

(defn date? [d] (instance? (type (t/date)) d))