streadway / amqp

Go client for AMQP 0.9.1
http://godoc.org/github.com/streadway/amqp
BSD 2-Clause "Simplified" License
4.87k stars 620 forks source link

Unit tests #471

Closed ErshovYS closed 4 years ago

ErshovYS commented 4 years ago

I try to testing my code (used this lib) and I have some problem. How to create some mock server for amqp?

My tries: 1) Use newServer and newSession from client test (for this I must copy all your lib in my tests). 2) Use https://github.com/NeowayLabs/wabbit and their FakeServer, but this lib response "connect refused" all time. 3) Use net.Listener, but response with amqp format - it's another problem.

How to use this lib in unit tests?

bombsimon commented 4 years ago

There are no test packages or test helpers nor any interfaces bundled in this repository. Back in 2019 #387 was opened which was aiming to implement interfaces for all public methods but it never got merged. Depending on your needs you could use that as an inspiration.

If you have trouble using wabbit but still want to use it you should ask for help in that repository. There are no open issues addressing connection refused so it's probably not an issue with the package since I think it's quite widely used.

You could create your own interfaces with the methods you use from the library and attach where needed instead of any amqp type. This is quite common and by defining your own interface you can easily generate mocks with e.g. minimock or gomock.1

A third alternative is to look into existing wrappers for this library. amqp-rpc (not only for RPC even though it's name) is a complete wrapper around this library which has methods to be used both as a receiving server or a calling client. The wrapper uses a function which is invoked before every message is sent that can be overridden for unit tests.

A fourth alternative would be to actually use a real server in your tests. Depending on what your needs are it might be the best way to do testing. You could use docker for local testing and development and rabbitmq-action for GitHub actions or rabbitmq service in Travis.

1 Example

type Publisher interface {
    Publish(exchange, key string, mandatory, immediate bool, msg amqp.Publishing) error
}

func somethingThatWillPublish(p Publisher) {
    // ...
    p.Publish("", "", false, false, someMessage)
    // ...
}

In production

conn, _ := amqp.Dial("amqp://guest:guest@localhost:5672/")
ch, _ := conn.Channel()

somethingThatWillPublish(ch)

In your unittests

type mockPublisherNoError struct {}

func (_ *mockPublisherNoError) Publish(_, _ string, _, _ bool, _ amqp.Publishing) error {
    return nil
}

mp := &mockPublisherNoError{}
somethingThatWillPublish(mp)