我应该如何测试我为Socket编写的包装器?

时间:2013-10-18 13:09:38

标签: ruby unit-testing rspec udp wrapper

因此,作为此Source Engine项目的一部分,我编写了一个基本上是套接字包装器的类。我想对它进行单元测试(它最终将成为我完成时发布的宝石,因此应该进行测试)

问题是......我对单元测试很新 - 而且我真的不知道应该如何测试这个东西。

相关代码在这里: https://github.com/misutowolf/freeman/blob/master/lib/source_socket.rb

1 个答案:

答案 0 :(得分:1)

首先,我会说你应该在意外的args进入构造函数时引发异常。假设您正在返回异常,那么此类的测试实际上非常简单。这应该让你开始:

# spec/lib/source_socket_spec.rb

describe SourceSocket do

  subject { source_socket }

  let(:source_socket) { SourceSocket.new(address, port, buffer) }

  let(:address) { double :address, class: SourceAddress, ip:   '1.2.3.4' }
  let(:port)    { double :port,    class: SourcePort,    num:  9876      }
  let(:buffer)  { double :buffer,  class: SourceBuffer                   }

  describe '#new' do
    context 'when the arguments are of the correct types' do
      it 'assigns the expected variables' do
        subject
        assigns(:address).should eq '1.2.3.4'
        assigns(:buffer).should  eq buffer
        assigns(:port).should    eq 9876
      end
    end

    context 'when the arguments are of incorrect types' do
      context 'when the address is of incorrect type' do
        let(:address) { double :address }
        expect { subject }.to raise_error('Error: Address argument is wrong type.')
      end

      context 'when the port is of incorrect type' do
        let(:port)    { double :port    }
        expect { subject }.to raise_error('Error: Port argument is wrong type.')
      end

      context 'when the buffer is of incorrect type' do
        let(:buffer)  { double :buffer  }
        expect { subject }.to raise_error('Error: Buffer must be a SourceBuffer object!')
      end
    end
  end

  describe '#to_s' do
    its(:to_s) { should eq '1.2.3.4:9876' }
  end

  describe '#open' do
    subject { source_socket.open(engine) }
    let(:engine) { double(:engine) }

    let(:socket) { double(:socket, connect: nil) }
    let(:packed) { double(:packed) }

    before do
      Socket.stub(:new).and_return(socket)
      Socket.stub(:pack_sockaddr_in).and_return(packed)
    end

    it 'assigns the engine variable' do
      subject
      assigns(:engine).should_not be_nil
    end

    it 'instantiates a Socket' do
      Socket.should_receive(:new).with(Socket::PF_INET, Socket::SOCK_DGRAM)
      subject
    end

    it 'assigns the socket variable' do
      subject
      assigns(:socket).should_not be_nil
    end

    it 'packs up the port and host' do
      Socket.should_receive(:pack_sockaddr_in).with(9876, '1.2.3.4')
      subject
    end

    it 'connects the socket' do
      socket.should_receive(:connect).with(packed)
    end
  end
end

请记住,有很多方法可以测试,RSpec docs是你最好的朋友。