Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anything with Browser.Navigation.Key cannot be tested #24

Open
sporto opened this issue Sep 13, 2018 · 23 comments
Open

Anything with Browser.Navigation.Key cannot be tested #24

sporto opened this issue Sep 13, 2018 · 23 comments

Comments

@sporto
Copy link

sporto commented Sep 13, 2018

When using Browser.application I will put the Key in my model for later use.

When testing I want to create a model, but I don't have a way to get a Key.
So I cannot test functions that take my Model.

Can test provide a way to get a navigation key?

Originally opened this here elm/browser#30

@mgold
Copy link
Collaborator

mgold commented Sep 14, 2018

If you are testing a function that calls pushUrl : Key -> String -> Cmd msg, you may want to pass it a String -> Cmd msg argument. This can be the real pushUrl model.key in production, and a stub for testing. I'm not sure how you're testing Cmds (elm-testable hasn't been upgraded for 0.19), but this is a fairly straightforward use of dependency injection.

@gampleman
Copy link
Contributor

I don't think this is necessarily for effect testing, but for anything that takes a model. So for example, when testing a view, that typically has a signature view : Model -> Html Msg, but one cannot construct a Model value in a test without the key.

@sporto
Copy link
Author

sporto commented Sep 14, 2018

In our case, we have two scenarios where we need this:

  • Testing views that take a Model (which has the key) like mentioned above.
  • Testing update functions which also take the key. We test that these update fns change the model as expected.

@mgold
Copy link
Collaborator

mgold commented Sep 15, 2018

Ah. Having dummyKey : Key that produces Cmd.none when used does sound helpful here.

You can also play around with record parameters, though I doubt this is news:

myView : { a | thing : Thing } -> Html Msg will accept a record with the thing field and anything else, so you can pass a Model or something simpler. This is actually a nice thing to do generally, if the fields aren't too numerous, to show that the view has limited dependencies.

type alias Model a = { a | thing : Thing } can be extended with { key : Key } to combine the records. It's a lot of boilerplate.

@timojaask
Copy link

timojaask commented Oct 31, 2018

I'm having a similar issue. I want to make sure that my init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg ) is returning a particular command depending on the Url passed by the Elm runtime. There seems to be currently no way to test this.

EDIT: Just realized I can’t generally compare Platform.Cmd’s, so that whole idea that I’d make sure that my main returns the right things seems to be doomed.

@andys8
Copy link

andys8 commented Nov 15, 2018

One can compare Cmd.none and other Cmds and they're not equal. I had fuzz tests making sure there is "nothing" happening by comparing with Cmd.none. Not being able to create Key made them unusable.

The other option to the approach #24 (comment) is to have a model with key: Maybe Key. This way the Model can be initialized in the tests, but Maybe has to be dealt with at runtime.

@rtfeldman
Copy link
Collaborator

Just a quick update: we're working on designs for a possible API to address this!

jenmei added a commit to oaktown/calliope that referenced this issue Mar 8, 2019
…e. Unfortunately, `Navigation.Key` is passed in from the runtime and there’s no way to create a testing stub for it currently. See elm-explorations/test#24 for updates.
jenmei added a commit to oaktown/calliope that referenced this issue Mar 8, 2019
…e. Unfortunately, `Navigation.Key` is passed in from the runtime and there’s no way to create a testing stub for it currently. See elm-explorations/test#24 for updates.
jenmei added a commit to oaktown/calliope that referenced this issue Mar 8, 2019
…e. Unfortunately, `Navigation.Key` is passed in from the runtime and there’s no way to create a testing stub for it currently. See elm-explorations/test#24 for updates.
jenmei added a commit to oaktown/calliope that referenced this issue Mar 8, 2019
…e. Unfortunately, `Navigation.Key` is passed in from the runtime and there’s no way to create a testing stub for it currently. See elm-explorations/test#24 for updates.
@bryce13950
Copy link

Is there any news on this?

@dkarter
Copy link

dkarter commented May 25, 2019

I'm also hitting my head against the wall. Just added routes to my app using Navigation and all my tests broke with no way of fixing them other than throwing away all of my tests or all of the router integration. Neither seem like acceptable workarounds.

I'm considering opening a PR to update the README for this project and elm/browser so other devs are warned before investing their time in these libraries. Is that a good idea?

@andys8
Copy link

andys8 commented May 26, 2019

Somebody pointed me to this interesting branch.

https://github.com/elm-explorations/test/compare/cmds

@Abubabubi
Copy link

Any updates?

@chalmagean
Copy link

This was recently released: https://package.elm-lang.org/packages/avh4/elm-program-test/3.1.0/

@Abubabubi
Copy link

Abubabubi commented Sep 10, 2019

That's already something, but still requires to change production code for tests.

@ceddlyburge
Copy link

I'm just upgrading to 0.19 at the moment and hitting this problem. I can't help feeling the situation is a bit crazy.

@duganc
Copy link

duganc commented Nov 9, 2019

Agreed with others on this thread. One of the benefits of FP is that testing should be easy so not providing any way to get a dummy key for testing seems like a real problem. Any further work being done on the PR above?

@danilol-zz
Copy link

I'm also in the same situation.

@ChickenProp
Copy link

ChickenProp commented Dec 13, 2019

Elmer provides Elmer.Navigation.fakeKey for this, using kernel code. If you don't want Elmer, another option would be to replace the Key in your model with a () -> Key. In your application you initialise it with \() -> realKey, and in your tests you initialize it with let fakeKey () = fakeKey () in fakeKey. But you won't be able to test any code that tries to force the value.

(Edit: and it means putting a function in your model, which is bad practice and IIRC limits the functionality of the debugger.)

@Bernardoow
Copy link

Any updates?

2 similar comments
@twiking
Copy link

twiking commented May 22, 2020

Any updates?

@jjant
Copy link

jjant commented Sep 28, 2020

Any updates?

@avh4
Copy link
Collaborator

avh4 commented Sep 28, 2020

While not a solution to the fundamental issue imposed by the Browser API, I added an example of how to test programs that use navigation keys with elm-program-test:

src: https://github.com/avh4/elm-program-test/blob/main/examples/src/NavigationKeyExample.elm
test: https://github.com/avh4/elm-program-test/blob/main/examples/tests/NavigationKeyExampleTest.elm
background info if you haven't used elm-program-test for testing Cmds before: https://elm-program-test.netlify.app/cmds.html

ZimbiX added a commit to ZimbiX/pathfinder-elm that referenced this issue Mar 21, 2021
The brian-watkins/elm-spec package actually supports initialising my app. I can't do this in elm-test due to `Browser.Navigation.Key` being inaccessible - see elm-explorations/test#24
@jjant
Copy link

jjant commented May 15, 2021

Any updates? @rtfeldman

@rtfeldman
Copy link
Collaborator

No updates, sorry!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests