Por que você escreveria testes de unidade para controladores?

22

Para mim, este é um teste unitário totalmente irrelevante e não entendo por que alguém passaria algum tempo escrevendo, pois há muito pouco valor a ganhar com isso. Eu saberia perfeitamente bem se esse controlador retornasse o tipo desejado executando o método em um navegador. Realmente, você acredita que é necessário um teste para isso e por quê?

public class ConstituencyControllerTests
{
    private ConstituencyController _constituencyController;
    private Mock<IConstituencyService> _IConstituencyServiceMock;

    public ConstituencyControllerTests() {
        _IConstituencyServiceMock = new Mock<IConstituencyService>();
    }

    [Test]
    public async Task I_Check_For_Return_Type_And_Result() {
        _constituencyController = new ConstituencyController( _IConstituencyServiceMock.Object );

        var result = await _constituencyController.Get();
        var content = ( (dynamic)result ).Content;

        Assert.IsEmpty( content );
        Assert.IsInstanceOf( typeof( System.Web.Http.Results.OkNegotiatedContentResult<IEnumerable<ListOfConstituencies>> ), result );
        _IConstituencyServiceMock.Verify( x => x.ListOfConstituencies(), Times.Once() );
    }
}
geadas
fonte
7
Não concorde com isso @gnat. Não se trata necessariamente de construções de linguagem, mas do tipo de resultado retornado por um controlador. Embora possa se resumir à mesma coisa quando você não tem hierarquia de herança, torna-se uma fera completamente diferente quando o controlador espera que os Ancestrais sejam retornados, o controlador retornou Person e agora Person mudou para não descender do Ancestor, mas do PeopleAncestor ... Também responde por que testar esse método pode ser uma boa idéia ...;) Os testes de unidade são destinados a detectar situações em que uma mudança em uma coisa c / quebraria outra.
Marjan Venema
Costumo concordar, normalmente não passo muito tempo testando os pontos de entrada do aplicativo. É como testar a unidade do método principal de um aplicativo de console. só faz muito pouco sentido para mim.
Mvision 30/01

Respostas:

29

O ponto principal é aqui:

Eu saberia perfeitamente bem se esse controlador retornasse o tipo desejado executando o método em um navegador

A testagem unitária é sobre a automação de unidades de código simples de teste sem regressão, não que você se veja. Você não quer fazer você mesmo sempre testando a unidade em seu aplicativo.

EDIT: Adicionando comentário @anotherdave:

É sobre a facilidade de dimensionamento. Testar um controlador em um navegador pode estar OK; que tal 10, 20, 50 controladores? Você escreverá o teste uma vez; pode ser necessário atualizá-lo quando você altera o controlador, que está sobrecarregado. Mas com que frequência você implanta? Certamente, uma verificação manual sempre que houver muito mais sobrecarga que o teste

Como alternativa à resposta de @ Vladislav , o teste de unidade absolutamente tudo pode ser um exagero e realmente indesejável. Se você precisar de algo mais leve, poderá fazer testes de não regressão de nível superior usando o Selenium. Certamente, você terá menos cobertura do que o teste de unidade, mas poderá obter uma cobertura razoável, que custará muito menos tempo fazendo testes de unidade e é mais flexível.

Ou seja, se você fizer o teste unitário de tudo, precisará atualizar um ou mais testes sempre que modificar um elemento simples.

Walfrat
fonte
4
Também para adicionar re: I would know perfectly well if this controller returned the wanted type by executing the method in a browser.- trata-se da facilidade de dimensionamento. Testar um controlador em um navegador pode estar OK; que tal 10, 20, 50 controladores? Você escreverá o teste uma vez; pode ser necessário atualizá-lo quando você altera o controlador, que está sobrecarregado. Mas com que frequência você implanta ? Certamente uma verificação manual sempre que houver muito mais sobrecarga que o teste.
precisa
"O teste de unidade é sobre automação" - Correto, no entanto, também é o teste de integração (Selenium / Webdriver / etc.). Não acho que seja necessariamente tão fácil e rápido que os testes de unidade sejam mais rápidos de implementar do que os testes de integração. Depende muito da abordagem, no entanto, se a realização de um teste de unidade eficaz exigir a zombaria de uma dúzia de serviços e chamadas diferentes feitos em cada um, um teste de integração poderá ser mais rápido de implementar e mais simples de manter (embora geralmente seja muito mais lento, sim) . A questão é que muito depende do contexto e da complexidade do código em teste.
Aroth
Comentário adicionado
@anotherdave
@aroth meu ponto era o oposto, o teste de unidade completo é um código que leva muito tempo e dificulta a alteração do código sem que haja um teste de unidade para alterar. Teste de integração é mais leve. É claro que você deseja que o teste de unidade seja algo muito complexo, mas não é porque você testou essa parte, que você deve testar tudo. Mais uma vez, vemos pessoas procurando a bala de prata onde ele não existe.
Walfrat
24

Por que você escreveria testes de unidade para controladores?

Porque sem conhecer o contexto, você não pode dizer com certeza se precisa testar isso ou aquilo. Aqui estão alguns motivos pelos quais você pode querer testar controladores:

  • O controlador pode conter lógica de fiação de serviço complexa, que é propensa a erros. Os serviços em si podem funcionar bem. É o resultado que você deseja testar e, por algum motivo, considerou não introduzir a camada de orquestração no aplicativo.
  • seus controladores contêm TODA a lógica comercial do aplicativo e os controladores são tudo o que você PODE testar (por favor, não pretenda que toda a sua vida você trabalhou com bases de código ideais, existem essas bases de código, acredite em mim)
  • sua equipe é composta por 99% de gênios e 1% da média de pessoas e você deseja manter esse 1% de erros no salário
Vladislav Rastrusny
fonte
2
Eu acrescentaria: "Você não pode prever quem no futuro se livrará do projeto, e os testes fazem parte do código auto-documentado"
Laiv
4
No ponto intermediário, um projeto que foi criado sem testes em mente pode não ser testável de outra maneira que um teste de controlador sem zombarias. Eu trabalho com uma equipe de C # que tem exatamente esse projeto sob seus cuidados, para que eles estejam escrevendo testes de controlador até poderem adicionar a estrutura necessária (interfaces, etc.) para poderem realizar testes mais detalhados.
Wayne Conrad
1

Concordo plenamente com o OP.

Um teste de unidade para um controlador é inútil. Você testa seus controladores implicitamente através de testes de regressão (usando Selenium, por exemplo).

Você deve TDD todos os componentes / objetos que o controlador usa e manter os controladores o mais fino possível. Então tudo é testado adequadamente. O que você quer ter certeza é que tudo funciona bem ao executar solicitações da Web. Isso é teste de regressão.

winkbrace
fonte
Talvez sim, mas essa não é uma resposta para a pergunta. De fato, é um argumento contra o uso de testes de unidade aqui.
23416 #
Acho que respondi à pergunta "você acredita que é necessário um teste para isso e por quê?"
Winkbrace 23/12/16
Sim, acho que o @winkbrace e compartilhamos os mesmos pensamentos sobre isso. Mas também acredito que é uma discussão sobre o que você deve fazer o teste de unidade e não. Eu acho que as pessoas testam demais e as coisas "erradas". no meu exemplo, testar o controlador oferece muito pouco valor, já que é tão fino e, esperançosamente, tem testes em torno dos serviços. Todas as respostas aqui são significativas e têm bons pontos, mas não é realmente possível marcar uma como resposta correta.
geadas
A lógica do controlador pode ser testada usando testes de integração automatizados, separados e distintos dos testes de unidade para componentes individuais.
precisa saber é o seguinte
-1: um teste de unidade para um controlador pode ser inútil. Os controladores são sobre transformação, mas às vezes a transformação em si é complexa e um desenvolvedor pode querer que ela seja coberta. Eu também acho que os testes de unidade 1) acabam validando uma implementação, não necessariamente validando o comportamento de alto nível, e 2) devem ser extremamente rápidos . Ambas as qualidades tornam os testes de unidade muito mais úteis durante o tempo de implementação; em outras palavras, eles são, em última análise ferramenta de um desenvolvedor, e apenas incidentalmente uma forma de qualidade do produto Validar.
rsenna