Autofixture: Obtenha a instância da Interface interna criada por AutoMoqData.

Criado em 26 abr. 2018  ·  8Comentários  ·  Fonte: AutoFixture/AutoFixture

Oi,

Estou tentando obter a instância da Interface Mocked interna criada por AutoMoqData para configurar a interface.

Existe uma maneira de fazer algo assim

[Theory, AutoMoqData]
public void Dummy(IFixture fixture, ComplexClassWithInnerInterface sut)
{
    fixture.GetInstance<IInnerInterfaceMockCreatedByAutoMoqData>().Setup(x => x.Method).Result(something);

    Assert.Equal(String.Empty, String.Empty);
}

Obrigado

question

Comentários muito úteis

Obrigado @xlecoustillier pela ótima resposta. Basicamente, sugiro fazer o mesmo, pois estou constantemente seguindo esse padrão em meus testes.

Mas para 30 interfaces é muito feio tê-los nos parâmetros do método.

Bem, este argumento parece um pouco estranho. Provavelmente, há algo errado com o design do código testado se você precisar configurar 30 dependências para fazer um cenário 😟 Estou 99% @ploeh sugeriria que você revise o código antes de prosseguir, de acordo com seu conselho, é recomendável ter no máximo 3-4 dependências 😅

Portanto, parece impossível obter simulações criadas automaticamente a partir do contêiner do aparelho. Eles não são injetados por padrão, portanto, se o aparelho tiver um método como o GetInstance, ele não retornará nada para os simulados criados automaticamente.

Não estou 100% certo de que entendi toda a mensagem claramente, mas pelo que entendi você está certo. Por padrão, todos os objetos gerados são transitórios e fixture não os preserva. Se você deseja fazer o objeto particular um singleton, você deve usar o fixture.Freeze<>() API ou [Frozen] atributo ou qualquer outro API adequado.
O comportamento padrão existente foi projetado para cobrir os cenários comuns e na maioria dos casos você _não quer_ ter o mesmo objeto por tipo.

Se você ainda está procurando a ajuda de nossa parte, forneça os requisitos mais precisos que você tem. Melhor, compartilhe código suficiente para demonstrar as limitações atuais e a meta que você gostaria de alcançar - isso ajudará a sincronizar melhor 😉

Obrigado.

Todos 8 comentários

Experimente

Mock.Get(sut).Setup(x => x.Method).Result(something);

Você obterá a instância do objeto não criada pelo Moq. acessando sut.

Isso realmente funcionará se a interface for uma propriedade pública.
Mock.Get (sut.InnerInterface) .Setup (x => x.Method) .Result (algo);

Mas e se a interface for simulada e o construtor injetado, registrado no contêiner IoC, mas não acessível em sut com uma propriedade pública?

Neste caso, você terá que congelar a simulação para garantir que a instância gerada também será injetada no sut:

[Theory, AutoMoqData]
public void Dummy(
    IFixture fixture, 
    [Frozen]Mock<YourInnerInterface> innerInterfaceMock,
    ComplexClassWithInnerInterface sut)
{
    innerInterfaceMock.Setup(x => x.Method).Result(something);
    sut.DoSomething();
    Assert.Equal(String.Empty, String.Empty);
}

Tenha o cuidado de sempre criar os mocks congelados antes do sut para que eles já existam quando o sut for criado e, portanto, sejam corretamente injetados.

Veja o blog de

Oi,
Eu já estava fazendo isso. Mas para 30 interfaces é muito feio tê-los nos parâmetros do método.
Seu código me lembrou que AutoMoqData não congela todas as interfaces simuladas. Portanto, parece impossível obter simulações criadas automaticamente a partir do contêiner do aparelho. Eles não são injetados por padrão, portanto, se o aparelho tiver um método como o GetInstance, ele não retornará nada para os simulados criados automaticamente. É por isso que obtenho duplicatas se congela o mock com a instância do fixture. A única maneira que vejo que funcionaria é se o sut pudesse ser atualizado com as simulações congeladas posteriores, mas isso seria feio. A maneira fácil é usar AutoMoqData para criar o IFixture, congelar e configurar mocks no método de teste e, em seguida, criar sut. Com essa configuração, posso criar um método auxiliar reutilizável para congelar e configurar simulações.

Obrigado

Obrigado @xlecoustillier pela ótima resposta. Basicamente, sugiro fazer o mesmo, pois estou constantemente seguindo esse padrão em meus testes.

Mas para 30 interfaces é muito feio tê-los nos parâmetros do método.

Bem, este argumento parece um pouco estranho. Provavelmente, há algo errado com o design do código testado se você precisar configurar 30 dependências para fazer um cenário 😟 Estou 99% @ploeh sugeriria que você revise o código antes de prosseguir, de acordo com seu conselho, é recomendável ter no máximo 3-4 dependências 😅

Portanto, parece impossível obter simulações criadas automaticamente a partir do contêiner do aparelho. Eles não são injetados por padrão, portanto, se o aparelho tiver um método como o GetInstance, ele não retornará nada para os simulados criados automaticamente.

Não estou 100% certo de que entendi toda a mensagem claramente, mas pelo que entendi você está certo. Por padrão, todos os objetos gerados são transitórios e fixture não os preserva. Se você deseja fazer o objeto particular um singleton, você deve usar o fixture.Freeze<>() API ou [Frozen] atributo ou qualquer outro API adequado.
O comportamento padrão existente foi projetado para cobrir os cenários comuns e na maioria dos casos você _não quer_ ter o mesmo objeto por tipo.

Se você ainda está procurando a ajuda de nossa parte, forneça os requisitos mais precisos que você tem. Melhor, compartilhe código suficiente para demonstrar as limitações atuais e a meta que você gostaria de alcançar - isso ajudará a sincronizar melhor 😉

Obrigado.

Sim, eu sugeriria que 30 dependências são demais.

Com relação a obter as dependências injetadas, usar o atributo [Frozen] , como @xlecoustillier sugere, é uma opção, e de fato a razão pela qual esse atributo existe originalmente.

Usar Mock.Get(sut.Dep1) também é uma opção que uso com frequência.

Mas e se a interface for [...] injetada pelo construtor, [...] mas não acessível em sut com uma propriedade pública?

Por que não expô-lo como uma propriedade, então? O que você compõe, você também pode expor. . Não quebra o encapsulamento para expô-lo.

Sinto vontade de adicionar @ploeh especificando que a melhor abordagem é expor dependências como propriedades de classe sem enriquecer sua abstração, o que não seria nada mais do que vazar sua implementação!

@ malylemire1 Fechando isto porque parece que nenhuma assistência adicional é necessária. Informe-nos se houver mais alguma coisa em que possamos ajudá-lo 😉

Obrigado mais uma vez por levantar a questão! 👍

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Eldar1205 picture Eldar1205  ·  5Comentários

malylemire1 picture malylemire1  ·  7Comentários

ploeh picture ploeh  ·  3Comentários

gtbuchanan picture gtbuchanan  ·  3Comentários

ploeh picture ploeh  ·  7Comentários