func (c *Conn) ByteWrite(write []byte) *Conn {
	c.mux.Lock()
	defer c.mux.Unlock()
	l := len(c.steps)
	if l != 0 && c.steps[l-1].write == nil && !c.steps[l-1].noResp && c.steps[l-1].err == nil {
		c.steps[l-1].write = write
	} else {
		c.steps = append(c.steps, &step{request: writeR, write: write})
	}
	return c
}
ByteWrite will set connection to expect provided bytes for write.
package mock
import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"sync"
	"time"
)
const (
	readR          = "read"
	writeR         = "write"
	countWritesOff = -90000000
)
type step struct {
	request      string
	write        []byte
	read         []byte
	err          error
	closed       bool
	waiting      bool
	done         bool
	noResp       bool
	wait         int
	count        int
	processRead  func(step int, count int) ([]byte, error)
	processWrite func(step int, count int) ([]byte, error)
}
type Conn struct {
	io.ReadWriteCloser
	done   chan struct{}
	mux    sync.Mutex
	errors []error
	steps  []*step
}
func NewConn() *Conn {
	return &Conn{
		done: make(chan struct{}),
	}
}
func (c *Conn) Read(out []byte) (int, error) {
	for {
		i, err := c.read(out)
		if i != -1 {
			return i, err
		}
		select {
		case <-time.After(2 * time.Millisecond):
		case <-c.done:
			return 0, io.EOF
		}
	}
}
func (c *Conn) read(out []byte) (int, error) {
	c.mux.Lock()
	defer c.mux.Unlock()
	d := 0
	for i, s := range c.steps {
		if s.done || s.closed {
			d++
			if d == len(c.steps) {
				return -1, io.EOF
			}
			continue
		}
		if s.processRead != nil && s.read == nil {
			var err error
			s.read, err = s.processRead(i, s.count)
			if err != nil {
				return 0, err
			}
		}
		if s.request == readR && !s.waiting {
			if s.wait > 0 && !c.steps[s.wait-1].done {
				continue
			}
			if s.err != nil {
				s.done = true
				return 0, s.err
			}
			n := copy(out, s.read)
			if n < len(s.read) {
				s.read = s.read[n:]
				return n, nil
			}
			if s.noResp {
				s.done = true
			} else {
				s.waiting = true
			}
			return n, nil
		}
		if s.request == writeR && s.waiting {
			if s.err != nil {
				s.done = true
				return 0, s.err
			}
			n := copy(out, s.read)
			if n < len(s.read) {
				s.read = s.read[n:]
				return n, nil
			}
			s.done = true
			return n, nil
		}
	}
	return -1, nil
}
func (c *Conn) Write(in []byte) (int, error) {
	for {
		select {
		case <-time.After(2 * time.Millisecond):
		case <-c.done:
			return 0, io.EOF
		}
		i, err := c.write(in)
		if i != -1 {
			return i, err
		}
	}
}
func (c *Conn) write(in []byte) (int, error) {
	c.mux.Lock()
	defer c.mux.Unlock()
	for i, s := range c.steps {
		if s.done || s.closed {
			continue
		}
		if s.processWrite != nil && s.write == nil {
			var err error
			s.write, err = s.processWrite(i, s.count)
			if err != nil {
				return 0, err
			}
		}
		if s.request == readR && s.waiting {
			if !bytes.Equal(s.write, in) {
				continue
			}
			s.done = true
			return len(in), nil
		}
		if s.request == writeR && !s.waiting {
			if s.wait > 0 && !c.steps[s.wait-1].done {
				continue
			}
			if s.err != nil {
				s.done = true
				return 0, s.err
			}
			if s.write != nil {
				if !bytes.Equal(s.write, in) {
					continue
				}
			}
			if s.noResp {
				s.done = true
			} else {
				s.waiting = true
			}
			return len(in), nil
		}
	}
	err := fmt.Errorf("mock: unexpected write\n% X", in)
	c.errors = append(c.errors, err)
	return 0, err
}
func (c *Conn) Close() error {
	c.mux.Lock()
	defer c.mux.Unlock()
	close(c.done)
	closed := false
	done := true
	for _, s := range c.steps {
		closed = closed || s.closed
		if s.closed {
			s.done = true
		}
		done = done && s.done
	}
	if !closed {
		err := errors.New("mock: unexpected call to Close")
		c.errors = append(c.errors, err)
		return err
	}
	if !done {
		err := errors.New("mock: closing unfinished scenario")
		c.errors = append(c.errors, err)
		return err
	}
	return nil
}
func (c *Conn) ByteRead(read []byte) *Conn {
	c.mux.Lock()
	defer c.mux.Unlock()
	l := len(c.steps)
	if l != 0 && c.steps[l-1].read == nil && c.steps[l-1].processRead == nil && !c.steps[l-1].noResp && c.steps[l-1].err == nil {
		c.steps[l-1].read = read
	} else {
		c.steps = append(c.steps, &step{request: readR, read: read})
	}
	return c
}
func (c *Conn) ErrRead(err error) *Conn {
	c.mux.Lock()
	defer c.mux.Unlock()
	if err == nil {
		err = errors.New("mock: generic read error")
	}
	l := len(c.steps)
	if l != 0 && c.steps[l-1].read == nil && c.steps[l-1].processRead == nil && !c.steps[l-1].noResp && c.steps[l-1].err == nil {
		c.steps[l-1].err = err
	} else {
		c.steps = append(c.steps, &step{request: readR, err: err})
	}
	return c
}