huytd / codedaily-v3

https://news.kipalog.com/
87 stars 14 forks source link

Write unit test #21

Open huytd opened 7 years ago

huytd commented 7 years ago

Hohoho! Welcome, Hacktoberfesters!

I know you will be here so I prepared some easy stuff for you. Enjoy it.

This project is slowly growing big and we're facing the death threat, we have no unit test!

This is a gold mine! You can open as many pull request as you can to cover all of the code we have in unit tests. But remember, each pull request must be done for a whole module (for example, one model per pull request is ok, but if you open 4 pull requests for 4 random function, it will be rejected right away).

Good luck guys!

Henning-K commented 6 years ago

By whole module, do you mean e.g. the whole src/bin/server.rs file but not necessarily the whole content of the src/bin/ folder?

huytd commented 6 years ago

Yeah, it should be file-by-file

Henning-K commented 6 years ago

Is there any reason for the fact that functions in src/bin/server.rs (e.g. register_user) return the diesel query result when all that is checked by the front-end is result != false?

This severely messes with the testability of the functions since some parameters in the return value differ depending on the state of the DB.

There's probably a way around this by invoking diesel database reset at the start (and end?) of each test and running tests with cargo test -- --test-threads=1 which limits the number of threads so that multiple tests don't depend on shared mutable state (aka a recipe for disaster).

huytd commented 6 years ago

bin/server.rs is actually a mess :D since most of the functions is just a route handler, that do a lot of works in it. I think the better solution for this one is to migrate all of the data manipulating away from the routing logic, to make it testable. Then, we should have the integrate testing which will connect to a real database.

Henning-K commented 6 years ago

A user on the #rust-beginners irc recommended a nice approach whereby the functions have the connection set up depending on whether a test is executed or not (through marking with #[cfg(test)] / #[cfg(not(test))]). The test-specific connection is then actually created with begin_test_transaction, meaning the transaction is not committed and the data changes from the multiple concurrent tests don't interfere with each other.

mdevlamynck commented 6 years ago

Why use PgConnetion instead of the trait Connection? You can then use the real PgConnection in production and using a mock type implementing Connection during tests. Plus that would allow to support other databases. That said it may be more boilerplate when writing tests, I'm not yet familiar with this in rust. What's your take on this?

I'll take a shot at testing the models.rs module.

huytd commented 6 years ago

Hey, I didn't know that we have Connection trait, when was it added? It's diesel.rs's built-in?

qcam commented 6 years ago

@mdevlamynck

What would be the pros and cons of using Connection?

mdevlamynck commented 6 years ago

Basically the same as using an interface vs using a concrete type in other languages.

Pros: would allow to:

Cons:

So I guess that's it for this idea.

Henning-K commented 6 years ago

I'm working on the server.rs unit tests and I'm done with all but the feed() function. Since there is another issue open which hints at a rewrite of that function, does it matter if I submit my PR without a test for feed()?