Writing testable Go code

Поделиться
HTML-код
  • Опубликовано: 14 янв 2025

Комментарии • 15

  • @acehanks
    @acehanks 4 года назад +3

    Just what I was looking for. Awesome content.

  • @zaffka
    @zaffka 4 года назад +4

    Good one! BTW, in case you didn't know - vscode has "tdt" macro for table tests.

    • @packagemain
      @packagemain  4 года назад +2

      Very handy, agree, I just wanted to show how to write from scratch.

  • @techst1442
    @techst1442 4 года назад +2

    Great content ! I am wondering that why did you return nil instead of err in line 31 at 8:11 ?

    • @packagemain
      @packagemain  4 года назад +4

      Great catch!!! that’s a typo, it should be err as last argument. You can check code on GitHub, it doesn’t have this typo

  • @GustavoDiaz93
    @GustavoDiaz93 4 года назад +1

    Great video 👌

  • @AlexOz
    @AlexOz 4 года назад +1

    Thanks a lot!

  • @YAPPOsc
    @YAPPOsc 4 года назад +1

    Table tasting might be looking good for small functions but in real life functions are usually bigger and more complex which makes the tests have multiple mocks and plenty of cases. In this case the lack of table testing is you can't run a particular test easily, especially from IDE (at least I haven't heard how I can do it). If only a single test out of 20 is failing and you wan't to debug it you either have to get tricky with breakpoints or to comment out the other test cases which sometimes leads to commenting out lots of variables because they became unused. I prefer to have separate t.Run for each case which uses the common body function. It allows to run a particular test and simplifies debugging a lot.
    Example:
    func MyTest(t *testing.T) {
    type TestCaseData struct {
    // data used in test cases. An analogue for table test strut
    }
    runFlow := func(testData TestCaseData) {
    // asserts
    }
    t.Run("test case 1", func(t *testing.T) {
    testData := TestCaseData{
    // test data 1
    }
    runFlow(testData)
    })
    t.Run("test case 2", func(t *testing.T) {
    testData := TestCaseData{
    // test data 2
    }
    runFlow(testData)
    })
    }
    Don't see downsides in comparison with table testing. Would like to know your opinion.

    • @packagemain
      @packagemain  4 года назад

      Agree, that works well for complex test functions. I actually never had problems with big tests, usually I try to make them fast, so I don't mind re-running the whole function. Integration tests can be slow to debug though, so your solution may work well for them.

  • @iggermanable
    @iggermanable 4 года назад +1

    Do not forget to close response body ;)

    • @packagemain
      @packagemain  4 года назад +1

      Also good point! Added it to the repo, unfortunately can't change in the video :)

    • @levani7851
      @levani7851 4 года назад +1

      @@packagemain a video about http client/transport/roundtripper would be amazing. there are very few resources on this.

  • @greyshopleskin2315
    @greyshopleskin2315 Год назад

    Instead of creating interfaces, just fetch the data out of the function and pass the list of repos to it.
    That way you don’t need to mock anything, just pass data to the function.

    • @packagemain
      @packagemain  2 месяца назад

      can you show a code example?

    • @greyshopleskin2315
      @greyshopleskin2315 2 месяца назад

      @@packagemain yes, but it’s 04:38 right now so it’s time to sleep 😴
      Tomorrow I will provide an example.
      If I don’t answer in 1-2 days you can ping me to remind me about this