É possível atribuir um out
/ ref
parâmetro usando Moq (3.0+)?
Eu olhei para usar Callback()
, mas Action<>
não suporta parâmetros de ref porque é baseado em genéricos. Também gostaria preferencialmente de colocar uma restrição ( It.Is
) na entrada do ref
parâmetro, embora eu possa fazer isso no retorno de chamada.
Eu sei que o Rhino Mocks suporta essa funcionalidade, mas o projeto no qual estou trabalhando já está usando o Moq.
It.IsAny<T>()
matcher-like (ref It.Ref<T>.IsAny
) a suporte para configuração.Callback()
e.Returns()
por meio de tipos de delegados personalizados que correspondem à assinatura do método. Métodos protegidos são igualmente suportados. Veja, por exemplo, minha resposta abaixo .Respostas:
O Moq versão 4.8 (ou posterior) aprimorou muito o suporte a parâmetros by-ref:
O mesmo padrão funciona para
out
parâmetros.It.Ref<T>.IsAny
também funciona para C # 7in
parâmetros (já que eles também são por-ref).fonte
out
, porém, funciona?Para 'fora', o seguinte parece funcionar para mim.
Eu estou supondo que o Moq analisa o valor de'pectedValue 'quando você chama o programa de instalação e se lembra dele.
Para
ref
também estou procurando uma resposta.Achei o seguinte guia de início rápido útil: https://github.com/Moq/moq4/wiki/Quickstart
fonte
Setup
EDIT : No Moq 4.10, agora você pode passar um delegado que possui um parâmetro out ou ref diretamente para a função de retorno de chamada:
Você precisará definir um delegado e instancia-lo:
Para a versão Moq anterior à 4.10:
Avner Kashtan fornece um método de extensão em seu blog que permite definir o parâmetro out de um retorno de chamada: parâmetros Moq, Callbacks e Out: um caso particularmente delicado
A solução é elegante e hacky. Elegante, pois fornece uma sintaxe fluente que se sente em casa com outros retornos de chamada do Moq. E hacky porque depende de chamar algumas APIs Moq internas por meio de reflexão.
O método de extensão fornecido no link acima não foi compilado para mim, por isso forneci uma versão editada abaixo. Você precisará criar uma assinatura para cada número de parâmetros de entrada que você possui; Forneci 0 e 1, mas estendê-lo ainda mais deve ser simples:
Com o método de extensão acima, você pode testar uma interface sem parâmetros como:
.. com a seguinte configuração do Moq:
Editar : Para oferecer suporte a métodos de retorno nulo, basta adicionar novos métodos de sobrecarga:
Isso permite testar interfaces como:
fonte
var methodCall = mock.GetType().GetProperty("Setup").GetValue(mock); mock.GetType().Assembly.GetType("Moq.MethodCall") .InvokeMember("SetCallbackResponse", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, methodCall, new[] { action });
mock.Setup(x=>x.Method(out d)).Callback(myDelegate).Returns(...);
...Callback(new MyDelegate((out decimal v)=>v=12m))...;
Esta é a documentação do site Moq :
fonte
Parece que não é possível fora da caixa. Parece que alguém tentou uma solução
Consulte esta publicação no fórum http://code.google.com/p/moq/issues/detail?id=176
esta pergunta Verifique o valor do parâmetro de referência com Moq
fonte
Para retornar um valor junto com a definição do parâmetro ref, aqui está um pedaço de código:
Em seguida, declare seu próprio representante que corresponde à assinatura do método a ser ridicularizado e forneça sua própria implementação de método.
fonte
Com base em Billy Jakes awnser, criei um método de simulação totalmente dinâmico com um parâmetro out. Estou postando isso aqui para quem achar útil (provavelmente apenas o futuro para mim).
fonte
Tenho certeza que a solução de Scott funcionou em um ponto,
Mas é um bom argumento para não usar a reflexão para espiar as APIs privadas. Está quebrado agora.
Consegui definir parâmetros usando um delegado
fonte
Isso pode ser uma solução.
fonte
Lutei com muitas das sugestões aqui antes de criar uma instância de uma nova classe 'Fake' que implementa qualquer interface que você esteja tentando zombar. Em seguida, você pode simplesmente definir o valor do parâmetro out com o próprio método.
fonte
Eu lutei com isso por uma hora esta tarde e não consegui encontrar resposta em lugar algum. Depois de brincar sozinho, consegui encontrar uma solução que funcionasse para mim.
A chave aqui é
mock.SetupAllProperties();
que irá remover todas as propriedades para você. Isso pode não funcionar em todos os cenários caso de teste, mas se tudo o que importa é conseguir oreturn value
deYourMethod
seguida, este trabalho bem.fonte