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

[Question] How I mock another service method? #1233

Closed
felinto-dev opened this issue Feb 19, 2021 · 8 comments
Closed

[Question] How I mock another service method? #1233

felinto-dev opened this issue Feb 19, 2021 · 8 comments

Comments

@felinto-dev
Copy link

I have a service that needs another service to work. I would like to mock him because that is the idea of unit tests.

Is there a file in this repository that can help me?

@jmcdo29
Copy link
Owner

jmcdo29 commented Feb 19, 2021

Yep, the RxJS-Sample/app.service has a service injecting a service and a mock for it.

@jmcdo29
Copy link
Owner

jmcdo29 commented Feb 19, 2021

Also, technically, anytime you're doing @InjectRepository() or @InjectModel(), you're injecting a service. This just happens to be a very specific service.

@felinto-dev
Copy link
Author

felinto-dev commented Feb 19, 2021

Hi!

Thanks for answering.
Your answer answers my question but I was not referring to that.
I'm sorry for not being clear.

const foundCat = await this.catModel.findOneAndUpdate({ _id }, cat).exec();

See for example this service to "update a cat". Instead of searching the repository directly if this cat exists and updating it, I could use another service called "getOne" to find out if the cat exists before updating it and returning an error if the cat does not exist.

The advantage of using a service instead of searching and updating by connecting to the database directly would be that I would not need to repeat the same error message on different services. For example, a service to "delete a cat".

My question would be how I could mock this service to "get a cat", because at certain times, it may be desirable for this service to return null, for example, to know what my system's behavior will be if the user type an invalid cat ID.

@jmcdo29
Copy link
Owner

jmcdo29 commented Feb 19, 2021

I recommend that you change the service name to "findOne" or change the service "getOne" to obligatorily return an exception if you don't find a cat. Find you use when you want to search for something but don't know where to find it and Get you use it when you know where a resource is and you only need to access it.

I'm gonna disagree with you here. Mainly for the fact that I know where I'm looking for it and what in looking by. We know it's the cat table, and we know the ID we're searching for. Sure we could get pedantic and say that maybe that ID exists, maybe it doesn't, but honestly that feels like arguing nest to argue.

The verbs Find and Get have a specific meaning in programming.

They have specific meaning in english too, but interpretation is subjective. In my mind, I wanted to find the cat based on the ID. If you feel incredibly strongly about it otherwise, feel free to leave a pull request fixing it (in all the places that use this pattern), with a link to some academic or well respected source able find vs get.

Now back to your question: if by "service" your mean a method of the save service, you'd just end up mocking the dependency's method that this method consumes. In general, you shouldn't really ever mock methods of the class you're trying to test, cause some runners, like jest, can run asynchronously and in parallel and end up giving you mixed results, so instead you should mock the lower dependencies and do an integration of the methods. That, or fully separate the tests to that you mock that method in one unit test suite but not the other.

@felinto-dev
Copy link
Author

felinto-dev commented Feb 19, 2021

In general, you shouldn't really ever mock methods of the class you're trying to test, cause some runners, like jest, can run asynchronously and in parallel and end up giving you mixed results, so instead you should mock the lower dependencies and do an integration of the methods.

"lower dependencies", would it be, for example, the database repository?

That, or fully separate the tests to that you mock that method in one unit test suite but not the other.

That is what I am looking for. In the example, I gave that the "updateCat" method depends on the "getOne" service, even if there is test coverage for the "getOne" method, a bug in this method would influence the "updateCat".

In these cases, could this not be a problem for unit tests that should only test a portion of code and mock external dependencies?

@felinto-dev felinto-dev changed the title [Question] How I mock another service? [Question] How I mock another service method? Feb 19, 2021
@jmcdo29
Copy link
Owner

jmcdo29 commented Feb 19, 2021

"lower dependencies", would it be, for example, the database repository?

Yes , exactly (wasn't sure what else to call them). The updateOne may depend on the findOne, but the findOne depends on the this.model.findOne so the dependency on this.model is what would need to be mocked.

a bug in this method would influence the "updateCat".

Yep, and that would be a drawback of having these methods depend on each other without good integration tests of the methods

In these cases, could this not be a problem for unit tests that should only test a portion of code and mock external dependencies?

It definitely could be a problem. Which is why there's integration and e2e testing. This repo has some e2e samples. I don't have anything explicitly for integration tests though.

@felinto-dev
Copy link
Author

You're awesome.

Could you close this issue?
Thank you.

@jmcdo29 jmcdo29 closed this as completed Feb 19, 2021
@jmcdo29
Copy link
Owner

jmcdo29 commented Feb 19, 2021

Thanks for the great discussion 😄 Hopefully it was helpful and will help others

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

2 participants