Pergunta

Então, eu tenho a seguinte classe:

public class MyClass {
  internal void A() {
    foreach(Thing thing in ThingArray)
      B(thing);
  }

  virtual internal void B(Thing thing)
  {
    //  do some stuff
  }
}

E então eu tenho o seguinte teste:

...
var testObject = new Mock<MyClass>(parameters);
testObject.Setup(t => t.B(It.IsAny<Thing>()));

test.Object.A();

test.Verify(t => t.B(It.IsAny<Thing>()), Times.Exactly(2));

E a verificar está falhando. Eu verifiquei, eo código está chamando o método real B (), em oposição a um método zombou B ().

Eu tenho um monte de código em execução, onde Moq funciona perfeitamente, e eu tenho de codificação tempo suficiente para perceber que devo estar fazendo algo errado aqui, mas para a vida de mim eu não posso vê-lo. Estive processo sob a suposição de que desde que eu estou chamando de teste. objeto .A (), as chamadas para B () não estão passando pelo Mock, mas que realmente não faz qualquer sentido para mim desde que uma chamada de qualquer outro objeto que funcionam da mesma forma ...

Então, por que na terra não é a configuração zombou sendo executado?

Edit: Sim, eu tenho os internos visíveis para o projeto de teste. Eu queria colocar isso no post original, já que eu sabia que alguém iria falar isso.

Quanto ao código real, é, infelizmente, muito própria, então não posso publicá-la. Vou ver se posso ajustar o código de amanhã para torná-lo realmente compilar.

Foi útil?

Solução

Eu não tenho certeza se as obras resposta do Gamlor. Parece que se você quiser executar uma instalação em um método onde você quer verificar se Class1.MethodA chama Class1.MethodB, MethodB (que é o que você faria a configuração on) tem que ser público (independentemente da InternalsVisibleTo). Eu escrevi um teste simples em uma situação semelhante e descobriu que uma vez eu fiz o meu público MethodB, Moq começou a trabalhar. Eu aposto que se você fez o seu método B público, ele iria trabalhar.

Eu suponho que este é um bug Castelo ou Moq mas eu não sei ao certo. Esperemos que alguém vai dialogar.

Eu sei que tornar público MethodB não é uma boa escolha. Mas isso é o que eu sei sobre a situação ...

Outras dicas

O objeto seu Mock tem de cumprir este critérios, a fim de fazer uma zombar com sucesso um método:

  • Tem que ser uma interface
  • Ou o método que deseja simulação tem que ser um método virtual e público.

Agora você também pode zombar método virtual interno, mas, a fim de permitir que você tem que dar Moq acesso aos seus componentes internos. Isso você pode fazer com:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

Esta tornar o acesso interno para o código-gerador de Moq.

Assim, para zombar de sua chamada MyClass.A você tem para fazer isso:

  1. Faça você o método A virtual.
  2. E fazer o seu público método ou permitir o acesso com

    [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
    

Ou, como disse, fazer uma interface que representa a API de MyClass.

Moq não quebra o código existente, mas em vez disso cria uma falsa vazio.

Isso significa que chamar testObject.Object.A () não executam seu código original, de modo B nunca é chamado.

Se você fingir seu zombando de uma interface, então isso faz sentido porque as interfaces não têm código, então, nem faria o mock.

Tente criar o mock assim (eu não tentar, então eu não sei se ele funciona):

var testObject= new Mock<MyClass> { CallBase = true };
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top