feat: add moq example
parent
581e34d210
commit
a7043b3f8e
|
@ -56,7 +56,10 @@ import (
|
||||||
)
|
)
|
||||||
</code></pre><p>And then in <code>Makefile</code>:<pre><code class=language-Makefile>build:
|
</code></pre><p>And then in <code>Makefile</code>:<pre><code class=language-Makefile>build:
|
||||||
go install github.com/golang/protobuf/protoc-gen-go
|
go install github.com/golang/protobuf/protoc-gen-go
|
||||||
</code></pre><p>We always get the version of build tools in <code>go.mod</code> each time we install it.<br>Future contributors will not cry anymore.<h3>Don't use cli libs (<a href=https://github.com/spf13/cobra>spf13/cobra</a>, <a href=https://github.com/urfave/cli>urfave/cli</a>) just for Go service</h3><p>What is the point to pass many params (<code>do-it</code>, <code>--abc</code>, <code>--xyz</code>) when what we only need is start service?<p>In my case, service starts with only config, and config should be read from file or environment like <a href=https://12factor.net/>The Twelve Factors</a> guide.<h3>Don't use <a href=https://github.com/grpc-ecosystem/grpc-gateway>grpc-ecosystem/grpc-gateway</a></h3><p>Just don't.<p>Use <a href=https://github.com/protocolbuffers/protobuf-go>protocolbuffers/protobuf-go</a>, <a href=https://github.com/grpc/grpc-go>grpc/grpc-go</a> for gRPC.<p>Write 1 for both gRPC, REST sounds good, but in the end, it is not worth it.<h3>Don't use <a href=https://github.com/uber/prototool>uber/prototool</a>, use <a href=https://github.com/bufbuild/buf>bufbuild/buf</a></h3><p>prototool is deprecated, and buf can generate, lint, format as good as prototool.<h3>Use <a href=https://github.com/gin-gonic/gin>gin-gonic/gin</a> for REST.</h3><p>Don't use <code>gin.Context</code> when pass context from handler layer to service layer, use <code>gin.Context.Request.Context()</code> instead.<h3>If you want log, just use <a href=https://github.com/uber-go/zap>uber-go/zap</a></h3><p>It is fast!<ul><li><p>Don't overuse <code>func (*Logger) With</code>. Because if log line is too long, there is a possibility that we can lost it.<li><p>Use <code>MarshalLogObject</code> when we need to hide some field of object when log (field is long or has sensitive value)<li><p>Don't use <code>Panic</code>. Use <code>Fatal</code> for errors when start service to check dependencies. If you really need panic level, use <code>DPanic</code>.<li><p>If doubt, use <code>zap.Any</code>.<li><p>Use <code>contextID</code> or <code>traceID</code> in every log lines for easily debug.</ul><h3>To read config, use <a href=https://github.com/spf13/viper>spf13/viper</a></h3><p>Only init config in main or cmd layer.<br>Do not use <code>viper.Get...</code> in business layer or inside business layer.<p>Why?<ul><li>Hard to mock and test<li>Put all config in single place for easily tracking</ul><h3>Don't overuse ORM libs, no need to handle another layer above SQL.</h3><p>Each ORM libs has each different syntax.<br>To learn and use those libs correctly is time consuming.<br>So just stick to plain SQL.<br>It is easier to debug when something is wrong.<p>But <code>database/sql</code> has its own limit.<br>For example, it is hard to get primary key after insert/update.<br>So may be you want to use ORM for those cases.<h3>If you want test, just use <a href=https://github.com/stretchr/testify>stretchr/testify</a>.</h3><p>It is easy to write a suite test, thanks to testify.<br>Also, for mocking, there are many options out there.<br>Pick 1 then sleep peacefully.<h3>If need to mock, choose <a href=https://github.com/matryer/moq>matryer/moq</a> or <a href=https://github.com/golang/mock>golang/mock</a></h3><p>The first is easy to use but not powerful as the later.<br>If you want to make sure mock func is called with correct times, use the later.<h3>Replace <code>go fmt</code>, <code>goimports</code> with <a href=https://github.com/mvdan/gofumpt>mvdan/gofumpt</a>.</h3><p><code>gofumpt</code> provides more rules when format Go codes.<h3>Use <a href=https://github.com/golangci/golangci-lint>golangci/golangci-lint</a>.</h3><p>No need to say more.<br>Lint or get the f out!<p>If you get <code>fieldalignment</code> error, use <a href=https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/fieldalignment>fieldalignment</a> to fix them.<pre><code class=language-sh># Install
|
</code></pre><p>We always get the version of build tools in <code>go.mod</code> each time we install it.<br>Future contributors will not cry anymore.<h3>Don't use cli libs (<a href=https://github.com/spf13/cobra>spf13/cobra</a>, <a href=https://github.com/urfave/cli>urfave/cli</a>) just for Go service</h3><p>What is the point to pass many params (<code>do-it</code>, <code>--abc</code>, <code>--xyz</code>) when what we only need is start service?<p>In my case, service starts with only config, and config should be read from file or environment like <a href=https://12factor.net/>The Twelve Factors</a> guide.<h3>Don't use <a href=https://github.com/grpc-ecosystem/grpc-gateway>grpc-ecosystem/grpc-gateway</a></h3><p>Just don't.<p>Use <a href=https://github.com/protocolbuffers/protobuf-go>protocolbuffers/protobuf-go</a>, <a href=https://github.com/grpc/grpc-go>grpc/grpc-go</a> for gRPC.<p>Write 1 for both gRPC, REST sounds good, but in the end, it is not worth it.<h3>Don't use <a href=https://github.com/uber/prototool>uber/prototool</a>, use <a href=https://github.com/bufbuild/buf>bufbuild/buf</a></h3><p>prototool is deprecated, and buf can generate, lint, format as good as prototool.<h3>Use <a href=https://github.com/gin-gonic/gin>gin-gonic/gin</a> for REST.</h3><p>Don't use <code>gin.Context</code> when pass context from handler layer to service layer, use <code>gin.Context.Request.Context()</code> instead.<h3>If you want log, just use <a href=https://github.com/uber-go/zap>uber-go/zap</a></h3><p>It is fast!<ul><li><p>Don't overuse <code>func (*Logger) With</code>. Because if log line is too long, there is a possibility that we can lost it.<li><p>Use <code>MarshalLogObject</code> when we need to hide some field of object when log (field is long or has sensitive value)<li><p>Don't use <code>Panic</code>. Use <code>Fatal</code> for errors when start service to check dependencies. If you really need panic level, use <code>DPanic</code>.<li><p>If doubt, use <code>zap.Any</code>.<li><p>Use <code>contextID</code> or <code>traceID</code> in every log lines for easily debug.</ul><h3>To read config, use <a href=https://github.com/spf13/viper>spf13/viper</a></h3><p>Only init config in main or cmd layer.<br>Do not use <code>viper.Get...</code> in business layer or inside business layer.<p>Why?<ul><li>Hard to mock and test<li>Put all config in single place for easily tracking</ul><h3>Don't overuse ORM libs, no need to handle another layer above SQL.</h3><p>Each ORM libs has each different syntax.<br>To learn and use those libs correctly is time consuming.<br>So just stick to plain SQL.<br>It is easier to debug when something is wrong.<p>But <code>database/sql</code> has its own limit.<br>For example, it is hard to get primary key after insert/update.<br>So may be you want to use ORM for those cases.<h3>If you want test, just use <a href=https://github.com/stretchr/testify>stretchr/testify</a>.</h3><p>It is easy to write a suite test, thanks to testify.<br>Also, for mocking, there are many options out there.<br>Pick 1 then sleep peacefully.<h3>If need to mock, choose <a href=https://github.com/matryer/moq>matryer/moq</a> or <a href=https://github.com/golang/mock>golang/mock</a></h3><p>The first is easy to use but not powerful as the later.<br>If you want to make sure mock func is called with correct times, use the later.<p>Example with <code>matryer/moq</code>:<pre><code class=language-golang>// Only gen mock if source code file is newer than mock file
|
||||||
|
// https://jonwillia.ms/2019/12/22/conditional-gomock-mockgen
|
||||||
|
//go:generate sh -c "test service_mock_generated.go -nt $GOFILE && exit 0; moq -rm -out service_mock_generated.go . Service"
|
||||||
|
</code></pre><h3>Replace <code>go fmt</code>, <code>goimports</code> with <a href=https://github.com/mvdan/gofumpt>mvdan/gofumpt</a>.</h3><p><code>gofumpt</code> provides more rules when format Go codes.<h3>Use <a href=https://github.com/golangci/golangci-lint>golangci/golangci-lint</a>.</h3><p>No need to say more.<br>Lint or get the f out!<p>If you get <code>fieldalignment</code> error, use <a href=https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/fieldalignment>fieldalignment</a> to fix them.<pre><code class=language-sh># Install
|
||||||
go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@latest
|
go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@latest
|
||||||
|
|
||||||
# Fix
|
# Fix
|
||||||
|
|
|
@ -215,6 +215,14 @@ Pick 1 then sleep peacefully.
|
||||||
The first is easy to use but not powerful as the later.
|
The first is easy to use but not powerful as the later.
|
||||||
If you want to make sure mock func is called with correct times, use the later.
|
If you want to make sure mock func is called with correct times, use the later.
|
||||||
|
|
||||||
|
Example with `matryer/moq`:
|
||||||
|
|
||||||
|
```golang
|
||||||
|
// Only gen mock if source code file is newer than mock file
|
||||||
|
// https://jonwillia.ms/2019/12/22/conditional-gomock-mockgen
|
||||||
|
//go:generate sh -c "test service_mock_generated.go -nt $GOFILE && exit 0; moq -rm -out service_mock_generated.go . Service"
|
||||||
|
```
|
||||||
|
|
||||||
### Replace `go fmt`, `goimports` with [mvdan/gofumpt](https://github.com/mvdan/gofumpt).
|
### Replace `go fmt`, `goimports` with [mvdan/gofumpt](https://github.com/mvdan/gofumpt).
|
||||||
|
|
||||||
`gofumpt` provides more rules when format Go codes.
|
`gofumpt` provides more rules when format Go codes.
|
||||||
|
|
Loading…
Reference in New Issue