Home > database >  Do I need to test functions which I know their result?
Do I need to test functions which I know their result?

Time:11-28

I have some methods under UserService class that is a high-level abstraction of my ORM which is Prisma. The reason I'm doing so is if I decided to use another ORM the rest of my application wouldn't need to change. For example, this method creates a user(it is simplified)

export class UserService {
  async create(data: UserCreateInput) {
    return await this.prisma!.user.create({
      data: { ...data },
      select: selectUserFields(),
    });
  }
}

my create method just runs Prisma's create method and returns the output. I do more stuff in my create method but in the end, it returns the result of Prisma's create method. in the tests, I have to mock the return value of the Prisma's create method and then check if it is what I specified which is kind of silly.

  it("should create a new user ", () => {
      mockPrisma.user.create.mockResolvedValue(defaultUser);
      expect(userService.create({ name: "jack" })).resolves.toEqual(defaultUser);
  });

Even this simple test cached me some errors, like forgetting to return a value, but I'm not satisfied with the benefits it gives to me. I don't want to spend time running silly tests.

Do you think it is silly too or should I keep it?

CodePudding user response:

I think some tests cases can inherently be trivial, however, thorough testing is important. So, I suggest you should add more cases as well, such as passing incorrect parameters, to test the failing case.

CodePudding user response:

Answers to this question are all going to be opinion based and contradict each other, which might mean the question could be closed. Also, a lot of cleverer people have said my opinion on this better than I have, and a lot of cleverer people think I am wrong... but all that said, I am going to try to answer anyhow.


TL;DR yes keep it. If you don't want to read millions of contradicting opinions about what tests are good, just write as many tests as you can on every level possible until you know the answer better than anybody who blogs about it. If you do want to read a bunch of people's opinions about this question, I have one here for you.


Somebody like Larry Wall said something like "I can show you how I do it, but I can't show you how you do it."

Personally, I would start with the goal of 100% test coverage at the highest level possible. Jest can tell you when you are leaving lines uncovered. I would test the API endpoints (or mounting components for client side stuff).
I would only write tests for individual functions like the one you have there in these cases:

  • The function covers so many cases that I can't or don't want to figure out how to call them all by calling the API. A date formatting function is a great example for this. You API might depend on the system date or something like that, so can only really test today's date or something like that, so you can just test your date formatter with like a hundred sample dates.
  • It's actually hard to figure out how to get the function right in the first place.. like it's got all kinds of if else || && in it and you actually benefit from test first (This is similar to what I heard DHH call "the TDD sweet spot" or something once)
  • There is no way to get 100% coverage with a high level test.. but I am totally sure I need a certain line of code, so while I could put /* istanbul ignore next */ or something and tell the coverage system, and my future self that I am not testing that line of code, instead I just prove I mean it by writing a "silly" test like you have said, and put a comment in my code about why it is necessary, and what the real world situation is that this code needs to work for that for some reason can't be covered by my high level tests.

Another side of your example is that a lot of people say you don't need to test external systems and external libraries, especially if they are famous and dependable. However, the biggest danger isn't that the Prism isn't working correctly - it's that you are wrong about how to use it. In your example you are using their mock.. which is great... because you hope that they have made sure that their mock is a good enough representation of their library, so you know you are using their library correctly. If you create your own mock for an outside library, it doesn't really prove anything, because your mock might reflect your misunderstanding of how that outside library works.

Also, if you update to the next major prism version, this might tell you pretty quick if you need to change your wrapper method... which is great. So if you wanna ignore everything else I have written, keep your silly test just for that.

Most importantly, if you just test everything as much as you can... you will quickly have your own answer to which tests are needed, and your own answer will be as good as anybody else's. Then I hope you come back and answer this question. I will bookmark it just in case.

  • Related