Pergunta

Eu estou trabalhando em zombando de algumas dependências externas e estou tendo problemas com uma classe 3o partido que leva em seu construtor uma instância de outra classe 3rd party. Esperemos que a comunidade SO pode me dar alguma direção.

Eu quero criar uma instância de simulação de SomeRelatedLibraryClass que leva em seu construtor uma instância simulada de SomeLibraryClass. Como posso zombar SomeRelatedLibraryClass desta maneira?

O código de repo ...

Aqui é um método principal que eu estou usando no meu aplicativo de console de teste.

public static void Main()
{
    try
    {
        SomeLibraryClass slc = new SomeLibraryClass("direct to 3rd party");
        slc.WriteMessage("3rd party message");
        Console.WriteLine();

        MyClass mc = new MyClass("through myclass");
        mc.WriteMessage("myclass message");
        Console.WriteLine();

        Mock<MyClass> mockMc = new Mock<MyClass>("mock myclass");
        mockMc.Setup(i => i.WriteMessage(It.IsAny<string>()))
            .Callback((string message) => Console.WriteLine(string.Concat("Mock SomeLibraryClass WriteMessage: ", message)));

        mockMc.Object.WriteMessage("mock message");
        Console.WriteLine();
    }
    catch (Exception e)
    {
        string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString());
        Console.WriteLine(error);
    }
    finally
    {
        Console.Write("Press any key to continue...");
        Console.ReadKey();
    }
}

Aqui é uma classe que eu tenho usado para embrulhar uma classe de terceiros e permitir que ele seja Moq'd:

public class MyClass
{
    private SomeLibraryClass _SLC;

    public MyClass(string constructMsg)
    {
        _SLC = new SomeLibraryClass(constructMsg);
    }

    public virtual void WriteMessage(string message)
    {
        _SLC.WriteMessage(message);
    }
}

Aqui estão dois exemplos de classes 3rd party que eu estou trabalhando com ( Você não pode editar estes ):

public class SomeLibraryClass
{
    public SomeLibraryClass(string constructMsg)
    {
        Console.WriteLine(string.Concat("SomeLibraryClass Constructor: ", constructMsg));
    }

    public void WriteMessage(string message)
    {
        Console.WriteLine(string.Concat("SomeLibraryClass WriteMessage: ", message));
    }
}

public class SomeRelatedLibraryClass
{
    public SomeRelatedLibraryClass(SomeLibraryClass slc)
    {
        //do nothing
    }

    public void WriteMessage(string message)
    {
        Console.WriteLine(string.Concat("SomeRelatedLibraryClass WriteMessage: ", message));
    }
}
Foi útil?

Solução

AFAIK, se a classe que você está tentando zombar fora não é virtual ou uma interface - você não pode zombar com Moq. Se a sua biblioteca parte 3 não implementa suas aulas, eu acho que você está sem sorte.

Outras dicas

Eu sugeriria usando o gateway padrão. Em vez de depender directamente sobre SomeRelatedLibraryClass, criar uma interface ISomeRelatedLibraryClassGateway. Expor todos os métodos SomeRelatedLibraryClass' que você precisa chamar com métodos da mesma assinatura em ISomeRelatedLibraryClassGateway.

public interface ISomeRelatedLibraryClassGateway {
  void WriteMessage(string message);
}

Em seguida, criar uma implementação que encaminha todas as chamadas para a terceira classe partido:

public class SomeRelatedLibraryClassGateway : ISomeRelatedLibraryClassGateway {
  private readonly SomeRelatedLibraryClass srlc;
  public SomeRelatedLibraryClassGateway(SomeRelatedLibraryClass srlc) {
    this.srlc = srlc;
  }

  void ISomeRelatedLibraryClassGateway.WriteMessage(string message) {
    srlc.WriteMessage(message);
  }
}

Agora, as classes em seu aplicativo que dependem SomeRelatedLibraryClass agora pode depender de ISomeRelatedLibraryClassGateway vez, e esta interface é fácil de zombar. O SomeRelatedLibraryClassGateway classe realmente não precisa de testes de unidade; tudo que faz é passar chamadas através. É faz necessidade de ser testado em um teste funcional, mas você pode fazer o teste funcional sem simulações.

Espero que isso ajude.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top