为了账号安全,请及时绑定邮箱和手机立即绑定

如何模拟 amqp.Dial 等库中的函数

如何模拟 amqp.Dial 等库中的函数

Go
大话西游666 2022-07-11 15:05:09
我正在研究一个小型 AMQP 消费者,我想测试我的消费者代码,但我很难模拟amqp.Dial. 我添加了一些接口,以便我可以模拟Connection并Channel添加一个属性,以便我可以控制拨号功能://consumer.gotype AmqpChannel interface {    ExchangeDeclare(name, kind string, durable, autoDelete, internal, noWait bool, args amqp.Table) error    QueueDeclare(name string, durable, autoDelete, exclusive, noWait bool, args amqp.Table) (amqp.Queue, error)    QueueBind(name, key, exchange string, noWait bool, args amqp.Table) error    Consume(queue, consumer string, autoAck, exclusive, noLocal, noWait bool, args amqp.Table) (<-chan amqp.Delivery, error)    Publish(exchange, key string, mandatory, immediate bool, msg amqp.Publishing) error}type AmqpConnection interface {    Channel() (AmqpChannel, error)    Close() error}type AmqpDial func(url string) (AmqpConnection, error)type MyConsumer struct {    HostDsn    string    channel    AmqpChannel    queue      amqp.Queue    connection AmqpConnection    DialFunc   AmqpDial}func (c *MyConsumer) Connect() error {    var err error    c.connection, err = c.DialFunc(c.HostDsn)...这似乎接近我想要达到的目标,我可以像这样指定我的测试:func TestConsumer(t *testing.T) {    mockCtrl := gomock.NewController(t)    defer mockCtrl.Finish()    var myConsumer = consumer.MyConsumer{        HostDsn: "test",        DialFunc: func(url string) (consumer.AmqpConnection, error) {            return mocks.NewMockAmqpConnection(mockCtrl), nil        },    }    _ = myConsumer.Connect()}但我不能amqp.Dial在主例程中将原件作为 dial-func 传递:myConsumer := consumer.MyConsumer{        HostDsn: fmt.Sprintf(            "amqp://%s:%s@rabbitmq:5672/?heartbeat=5s",            os.Getenv("RABBITMQ_USER"),            url.QueryEscape(os.Getenv("RABBITMQ_PASSWORD")),        ),        DialFunc: amqp.Dial,    }给./main.go:28:9: cannot use amqp.Dial (type func(string) (*amqp.Connection, error)) as type consumer.AmqpDial in field value我希望/认为,作为amqp.Connection实现AmqpConnection接口,这会起作用:/模拟方法的正确方法是amqp.Dial什么?
查看完整描述

1 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

给定以下类型:


type AmqpChannel interface {

    ExchangeDeclare(name, kind string, durable, autoDelete, internal, noWait bool, args amqp.Table) error

    QueueDeclare(name string, durable, autoDelete, exclusive, noWait bool, args amqp.Table) (amqp.Queue, error)

    QueueBind(name, key, exchange string, noWait bool, args amqp.Table) error

    Consume(queue, consumer string, autoAck, exclusive, noLocal, noWait bool, args amqp.Table) (<-chan amqp.Delivery, error)

    Publish(exchange, key string, mandatory, immediate bool, msg amqp.Publishing) error

}


type AmqpConnection interface {

    Channel() (AmqpChannel, error)

    Close() error

}


type AmqpDial func(url string) (AmqpConnection, error)

您可以创建委托给实际代码的简单包装器:


func AmqpDialWrapper(url string) (AmqpConnection, error) {

    conn, err := amqp.Dial(url)

    if err != nil {

        return nil, err

    }

    return AmqpConnectionWrapper{conn}, nil

}


type AmqpConnectionWrapper struct {

    conn *amqp.Connection

}


// If *amqp.Channel does not satisfy the consumer.AmqpChannel interface

// then you'll need another wrapper, a AmqpChannelWrapper, that implements

// the consumer.AmqpChannel interface and delegates to *amqp.Channel.

func (w AmqpConnectionWrapper) Channel() (AmqpChannel, error) {

    return w.conn.Channel()

}


func (w AmqpConnectionWrapper) Close() error {

    return w.conn.Close()

}


查看完整回答
反对 回复 2022-07-11
  • 1 回答
  • 0 关注
  • 113 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号