Fork me on GitHub
#clojurescript
<
2022-11-17
>
Steph Crown09:11:56

Hi guys. What Clojure library do you suggest I use to write tests that mock api requests?

chico09:11:29

It’s not a clojure library, but I’ve been using https://mswjs.io/ and been very happy with it.

p-himik09:11:17

Hey Steph. Please avoid cross-posting within such a short time frame. Especially if you're interested in a CLJ-only or a CLJ/CLJS library and not a CLJS-only one.

Steph Crown09:11:32

I apologize for that.

shawn09:11:30

hello. can anyone help with confirming whether these two are functionally equivalent:

(ns app.relay-env
  (:require ["relay-runtime" :refer [Environment, Network, RecordSource, Store]]))

(defn fetchGraphQL [text, variables]
  (js/fetch (str "" {:method "POST" :headers {:content-type "application/json"} :body (.stringify js/JSON (clj->js {:query text :variables variables}))})) (.then #(.json %)))

(defn fetch-relay [params, variables]
  (fetch-gql params.text variables))
(def environment
  (new Environment {:network (.create Network fetch-relay) :store (new Store (new RecordSource))}))
and js
import {Environment, Network, RecordSource, Store} from 'relay-runtime';
async function fetchGraphQL(text, variables) {
  const response = await fetch('', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: text,
      variables,
    }),
  });

  return await response.json();
}

async function fetchRelay(params, variables) {
  return fetchGraphQL(params.text, variables);
}

export default new Environment({
  network: Network.create(fetchRelay),
  store: new Store(new RecordSource()),
});
for some reason, when I use this, I get this error: `RelayModernEnvironment.js:223 Uncaught TypeError: Cannot read properties of undefined (reading 'check') at _proto.check (RelayModernEnvironment.js:223:17)` which seems to suggest that there is at least a missing store, which may mean that I'm not instantiating store correctly

thheller09:11:54

they are not equiv no

thheller09:11:14

(def environment
  (new Environment {:network (.create Network fetch-relay) :store (new Store (new RecordSource))}))

thheller09:11:47

this is passing a clojure map with keywords to the constructor. which it won't understand. so you need to pass a JS object. either by using the #js literal, or using clj->js

thheller09:11:10

(defn fetchGraphQL [text, variables]
  (js/fetch (str "" {:method "POST" :headers {:content-type "application/json"} :body (.stringify js/JSON (clj->js {:query text :variables variables}))})) (.then #(.json %)))

thheller09:11:27

same here. the str also seems wrong

shawn09:11:47

awesome. thank you very much!

thheller09:11:00

(ns app.relay-env
  (:require ["relay-runtime" :as rr]))

(defn fetch-gql [text variables]
  (-> (js/fetch ""
        (clj->js {:method "POST"
                  :headers {:content-type "application/json"}
                  :body (js/JSON.stringify (clj->js {:query text :variables variables}))}))
    (.then #(.json %))))

(defn fetch-relay [^js params variables]
  (fetch-gql (.-text params) variables))

(def environment
  (rr/Environment.
    #js {:network (rr/Network.create fetch-relay)
         :store (rr/Store. (rr/RecordSource.))}))
maybe

thheller09:11:28

(I don't like a bunch of refer, but you can do that if you want to)

shawn09:11:15

This fixed it! thank you for getting me through this

Olaleye Blessing10:11:49

Good day here! Is there a way to write unit tests for functions that interact with the browser? Like a function that connects Metamask. You know this type of function needs to open Metamask and allow the user to connect. SO how do I write a unit test for this type of function?

thomas12:11:14

you can probably mock it. Unit test are usually run with out external dependencies. If you want to test those integrations you are more looking towards and end-to-end or integration test.

Olaleye Blessing12:11:44

Thanks. How do I do so in E2E/integration tests?

thomas12:11:28

I guess that depends on the E2E framework you are using. have a look at the docs I suggest.

localshred13:11:23

If you want round-trip tests against the browser look into selenium testing with the limo clojure library (wraps the selenium java api)

thomas09:11:55

If I remember correctly there is a native clojure web driver as well. have a google.

Steph Crown12:11:48

Hi guys. Is there a way to make use of a Clojure library in a ClojureScript project?

cjohansen12:11:49

If it is written in cljc files

p-himik12:11:24

Or if the CLJ code that you need to use is just for macros.

Steph Crown12:11:31

Well, I dont know what exactly I want to use. But when I try to require the dependency, it throws an error.

The required namespace "ring.mock.request" is not available, it was required by "test/main_test.cljs".
"ring/mock/request.clj" was found on the 

cjohansen12:11:41

You’re trying (either directly or indirectly) to load the ring.mock.request namespace, which is in a clj file, into your ClojureScript program. That is not possible.

Steph Crown12:11:52

Alright. So do you know any library written in ClojureScript that I can use to mock and test API requests?

dumrat12:11:40

@U041MRNEQ7J Are you testing server code or client code?

Rupert (Sevva/All Street)13:11:42

You could try using your existing API request function but using https://clojuredocs.org/clojure.core/with-redefs to replace your function implentation with a fake one.

(with-redefs [http/post (fn [url] {:body "Goodbye world"})]
    (is (= {:body "Goodbye world"} (http/post ""))

localshred14:11:39

torture/spy is a clj(s) mock/stub/spy library that you could use to stub out your API calls https://github.com/alexanderjamesking/spy

localshred14:11:36

if you've never implemented mocks/stubs before, I'd use a library to manage it for you instead of going the with-redefs route

Rupert (Sevva/All Street)14:11:13

@U5RFD1733 - I can understand that a mocking library adds extra value, but I'm not sure someone should be put of from using with-redefs? The example I posted above was pretty trivial and has no library dependencies and (because it is clojurescript) it doesn't even have the multi-threading gotcha of with-redefs.

👍 1
Steph Crown14:11:19

I am testing clientside code.

Steph Crown14:11:17

I'll try with-derefs and get back to you. Thanks, @UJVEQPAKS

👍 1
Olaleye Blessing17:11:37

@UJVEQPAKS

(with-redefs [http/post (fn [url] {:body "Goodbye world"})]
    (is (= {:body "Goodbye world"} (http/post ""))
http/post : which library are you using for the http? Is it https://github.com/r0man/cljs-http ?

rgm18:11:38

> if you've never implemented mocks/stubs before, I'd use a library to manage it opinions vary, but I've come to believe adding a mock library encourages more mocking. I prefer with-redefs to make me think harder about whether mocking to make a test work is worth the big downside: it provides an opportunity for my code's behaviour to wander out from under my test, but the test keeps passing.

rgm18:11:05

sometimes it's the right tool, but for me if it's often enough that I reach for a library, I try to stop and rethink my life choices.

Rupert (Sevva/All Street)22:11:04

@U045UJUEH0U - that was just an example. cljs-http is a good choice and very popular.

Falak Shair14:11:52

Hi, I'm new to Clojure and ClojureScripts. I have some basics of Clojure programming, but I need some help learning ClojureScripts (Reagent, re-frame). I'm struggling to find a good source. I hope you guys can help me find resources where I can learn by doing projects.

Falak Shair15:11:28

Are there any free resources?

Rupert (Sevva/All Street)15:11:26

@U04AP46SGDU reagent is a resoanable starting point, but note that there are other options on the frontend like https://github.com/roman01la/uix which gives you the full power of React Hooks in Clojure. Another option if you are new to Clojure and ClojureScript is to build a server side rendered web app just with Clojure (https://github.com/ring-clojure/ring + https://github.com/weavejester/hiccup). If you need additional interactivity you can layer in https://github.com/bigskysoftware/htmx and https://github.com/bigskysoftware/_hyperscript in your hiccup where you need it.

Falak Shair15:11:01

@UJVEQPAKS I have to work on a project which uses reagent

👍 1
phill01:11:51

I found Eric Normand's educational videos very, very helpful for getting me to a place where I could solve my own problems.

👍 1
andy.fingerhut15:11:49

@U04AP46SGDU If you are being paid to work on a project that uses reagent, you could consider asking those paying you, if they would also pay for one of the training courses.

Rupert (Sevva/All Street)08:11:25

The basics of reagent can be learned in about a day - it has a powerful r/atom function + hiccup syntax + follows the rules of react. Re-frame attempts to create a structured framework around re-agent and decouple UI from business logic from backend. Most people learn I know learned re-frame from the documentation in the https://day8.github.io/re-frame/re-frame/ which is quite detailed.

👍 1
George17:11:33

hi, I have a go block in a cljs file, and on page refresh I get a "Uncaught (in promise) ReferenceError: sb__3296__auto__ is not defined". The weird thing is this code was working before (it runs js/fetch and uses the returned json to change content in the html). Any ideas what a typical reason for this might be?

George17:11:39

Seems to be some oddity with Firefox....a different browser works

p-himik20:11:19

Might be some weird race condition? Can't tell for sure without a reproducer.