문제

C#의 System.net.sockets.socket 클래스를 조롱하려고합니다. Nunit Mocks를 사용해 보았지만 콘크리트 클래스를 조롱 할 수는 없습니다. 나는 또한 Rhino Mocks를 사용하려고 시도했지만 Send (byte [])가 호출 될 때 Pocketexception을 던 졌기 때문에 실제 버전의 클래스를 사용하는 것처럼 보였습니다. 조롱 프레임 워크를 사용하여 소켓 모의를 성공적으로 만들고 사용한 사람이 있습니까?

도움이 되었습니까?

해결책

MOQ로 이런 종류의 문제를 해결할 때마다 결국 조롱 할 수없는 것을 추상화하기 위해 인터페이스를 만들게됩니다.

따라서 인스턴스에서는 Send 메소드를 구현하는 Isocket 인터페이스가있을 수 있습니다. 그런 다음 대신 조롱 프레임 워크를 조롱하십시오.

실제 코드에는 이와 같은 수업이 있습니다.

public class MySocket : ISocket
{
  System.Net.Sockets.Socket _socket;

  public void MySocket(System.Net.Sockets.Socket theSocket)
  {
    _socket = theSocket;
  }

  public virtual void Send(byte[] stuffToSend)
  {
    _socket.Send(stuffToSend);
  }

}

그것이 당신의 요구를 충족시키는 지 확실하지 않지만 옵션입니다.

다른 팁

Send 메소드를 호출 할 때 Pocketexception을 얻는 이유는 Send가 재정의 가능한 메소드가 아니기 때문입니다. Rhinomocks가 속성이나 방법의 동작을 조롱 할 수 있으려면 인터페이스에 정의되어야합니다 (우리는 모의를 만들어냅니다).

이에 대한 유일한 해결책은 Mockable Wrapper 클래스를 만드는 것입니다 (ThinkZig가 제안한대로).

ThinkZig 제안 (소켓의 어댑터 클래스)을 사용하여 예제 콘솔 응용 프로그램을 만들었습니다. Rhinomocks와 Nunit을 사용합니다. 여기에서 다운로드 할 수 있습니다. System.net.sockets.socket을 조롱하는 방법.

위의 클래스는 전송 방법 만 조롱합니다. 이것은 실제로 소켓을 조롱합니다. 모든 소켓을 상속 한 다음 isocket 인터페이스를 구현합니다. isocket은 조롱 해야하는 소켓 방법 또는 속성의 서명을 구현해야합니다.

//internal because only used for test code
internal class SocketWrapper : Socket, ISocket
{
    /// <summary>
    /// Web Socket
    /// </summary>
    public SocketWrapper():base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    {
    }

    //use all features of base Socket
}

인터페이스는 두 가지 방법이 거부 된 것으로 보입니다.

public interface ISocket
{
    void Connect(IPAddress address, int port);
    int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode);
}

그것들을 사용하는 클래스에는 2 개의 생성자가 있습니다. 하나는 테스트를 위해 isocket을 주입 한 다음 응용 프로그램에서 사용하는 자체 소켓을 만드는 것입니다.

public class HTTPRequestFactory3
{
internal ISocket _socket;


    /// <summary>
    /// Creates a socket and sends/receives information.  Used for mocking to inject ISocket
    /// </summary>
    internal HTTPRequestFactory3(ISocket TheSocket)
    {
     _socket = TheSocket as ISocket;
     this.Setup();
    }

    /// <summary>
    /// Self Injects a new Socket.
    /// </summary>
    public  HTTPRequestFactory3()
    {
        SocketWrapper theSocket = new SocketWrapper();
        _socket = theSocket as ISocket;
        this.Setup();
    }
}

그런 다음 테스트에서 ISOKET을 생성하고 기대치를 설정하고 위의 클래스에서 실제 소켓과 함께 사용할 동일한 코드를 실행하는지 확인할 수 있습니다. 이 테스트는 해당 섹션 코드를 검증합니다.

   [Test]
   public void NewSocketFactoryCreatesSocketDefaultConstructor()
        {
            webRequestFactory = new HTTPRequestFactory3();
            Assert.NotNull(webRequestFactory._socket);
            Socket testSocket = webRequestFactory._socket as Socket;
            Assert.IsInstanceOf<Socket>(testSocket);
        }

ThinkZig가 말한대로 모든 메소드 호출을 .NET 소켓으로 전달하는 코드에서 인터페이스를 만들고 조롱하고 코드에서 래퍼 클래스를 구현하는 것이 좋습니다. 이 링크를보십시오. 동일한 문제입니다. 단위 테스트를 위해 C#의 파일 시스템을 어떻게 조롱합니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top