Hey,

I don't think the statement about "assert going against the best practices 
in go unit tests" stands against the reality, sorry. One definitely doesn't 
have to use a separate assertion package to write unit-tests in Go, 
comparing to some other programming languages. But there is really no much 
difference between using an assertion of t.Fail-ing manually.

In our project, we use testify assertions (only for statistics: our 
monorepo is ~400K lines of Go code with every package covered with 
unit-tests) and it works great just by reducing the total number of lines 
in our test files and making them much more manageable (we have unit-tests 
files that over years has grown over 3K+ LOC now).

Depending on the interface, we usually create a separate "controlled" 
implementation, that we use in unit-tests. E.g. if we implemented a 
DataStore, we would have an in-memory implementation with additional 
Setter-methods, that accepted an optional "hook", that allowed us to return 
an error.

We don't use "testify/mock" because we aren't interested in verifying the 
calls or the arguments that were passed to the mock. Usually, it's easier 
to write a fake implementation. I.e. our testing implementations are more 
"fakes" than "mocks".

One neat thing about that approach is that testing implementation doesn't 
always have to expose lots of knobs. If one unit-test needs to tune the 
behaviour, you can always stub the dependency right in-place and use it for 
this single test only. E.g.

type testDataStore struct {
    callFooFunc() error
}

func (s *testDataStore) Foo() error {
    return s.callFooFunc()
}

func TestSomething(t *testing.T) {
    ds := &testDataStore {
        callFooFunc: func() error {
           return fmt.Errorf("a very specific error that make sence to test 
against in this test only")
        }
    }
    // ยทยทยท
}

Hope that makes sense.

On Thursday, October 1, 2020 at 6:26:19 PM UTC+2 krish...@gmail.com wrote:

> We are working on a full scale production app with go backend.
>
> For unit tests, we need to mock the dependent interfaces either by 
> creating our own mock implementation of the interface or by using third 
> party packages like *testify/mocks.*
>
> If we use testify, there will be a tendency for the developers to use *assert 
> *statements which is against the best practices in go unit tests. (We use 
> t.Fail instead of asserts)
>
> If we create manual mocks, we will end up creating two implementations for 
> each interface, one for the program and another for the unit testing. Also 
> we cannot test by mocking with different outputs from the dependencies. 
> example if the dependency return an error.
>
> Please suggest which the right approach here.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/6102c3f1-d398-4e0b-9cc8-fc4a848f4c7bn%40googlegroups.com.

Reply via email to