t
  • Entreguei o primeiro projeto em #WRT gastei mais tempo configurando o ambiente do que desenvolvendo! A #nokia poderia melhorar isso..

Posts recentes

Comentários recentes

Mock Object com exemplos em ASP.NET MVC

Postado por Daniel Fonseca Castro - Tuesday, June 29, 2010 7:14 AM

Vou iniciar esse post com um link que define o que é Mock Object http://pt.wikipedia.org/wiki/Mock_Object , neste post quero mostrar como criar Mock Object com a framework Moq http://code.google.com/p/moq/ que na minha opinião é simples e possui os recursos necessários para o nosso dia a dia.

Para montar os exemplos vou aproveitar os testes do AccountController (arquivo AccountControllerTest.cs) criado por padrão, estou utilizando o VS 2010 e ASP.NET MVC 2.

Entender as dependências do AccountController será o nosso primeiro passo, ele depende de duas interfaces IFormsAuthenticationService e IMembershipService, e a Action ChangePassword depende da interface IIdentity, para nossa felicidade as dependências são para uma abstrações e por isso podemos criar Mock Object. Note que já existe Mock para todas as dependências, só que os Mocks foram criados sem o auxilio de uma framework , não existe problema algum nisso, mais uma framework pode fazer o trabalho de forma mais simples e ainda trazer outros benefícios , por exemplo, pode viabilizar/ajudar na pratica de TDD.

Agora que já identificamos as dependências podemos refatorar o código existe, o método GetAccountController é o método responsável pela criação do AccountController com todos os Mocks necessários e é esse método que vamos refatorar, vou utilizar a framework Moq para substituir as classes MockHttpContext e MockMembershipService , veja o código abaixo:


private static AccountController GetAccountController()
{
    AccountController controller = new AccountController();
    controller.FormsService = new MockFormsAuthenticationService();

    MembershipServiceMock(controller);
    ControllerContextMock(controller);

    return controller;
}

private static void ControllerContextMock(AccountController controller)
{
    var mockControllerContext = new Mock<ControllerContext>();
    mockControllerContext.Setup(user => user.HttpContext.User.Identity.Name).Returns("someUser");
    controller.ControllerContext = mockControllerContext.Object;
}

private static void MembershipServiceMock(AccountController controller)
{
    var mockMembershipService = new Mock<IMembershipService>();
    mockMembershipService.Setup(password => password.MinPasswordLength).Returns(10);

    //Mock do método ChangePassword
    mockMembershipService
        .Setup(changePassword => changePassword.ChangePassword(It.IsAny<string>()
		,It.IsAny<string>()
		, It.IsAny<string>()))
        .Returns<string, string, string>((string userName, string oldPassword, string newPassword) =>
        {
            return (userName == "someUser" 
			&& oldPassword == "goodOldPassword" 
			&& newPassword == "goodNewPassword");
        });

    //Mock do método ValidateUser
    mockMembershipService
        .Setup(validateUser => validateUser.ValidateUser(It.IsAny<string>(), It.IsAny<string>()))
        .Returns<string, string>((string userName, string password) =>
        {
            return (userName == "someUser" && password == "goodPassword");
        });

    //Mock do método CreateUser
    mockMembershipService
        .Setup(createUser => createUser.CreateUser(It.IsAny<string>()
		, It.IsAny<string>()
		, It.IsAny<string>()))
        .Returns<string, string, string>((string userName, string password, string email) =>
        {
            if (userName == "duplicateUser")
                return MembershipCreateStatus.DuplicateUserName;

            // verify that values are what we expected
            Assert.AreEqual("goodPassword", password);
            Assert.AreEqual("goodEmail", email);

            return MembershipCreateStatus.Success;
        });

    controller.MembershipService = mockMembershipService.Object;
}

Agora vamos analisar o método ControllerContextMock , no primeiro passo crio uma instância da classe Mock essa instância é genérica e por isso passo o tipo do objeto que vou criar o Mock Object que neste caso é ContextController, no segundo passo o método Setup recebe uma expressão lambda aonde defini que a framework deve trabalhar na propriedade Name da interface IIdentity , e o método Returns retorna o valor para propriedade, note que somente isso é o suficiente para a framework criar todas as instâncias necessárias e definir o valor para propriedade. Por fim recupero o objeto "mockado" através da propriedade Object.

Criar Mock Object para uma propriedade é uma tarefa relativamente simples, agora vamos analisar o método MembershipServiceMock que possui exemplos de Mocks para os métodos.O método Setup faz a mesma coisa define através de uma expressão lambda aonde a framework deve trabalhar, o método ChangePassword recebe três parâmetros do tipo String e para definir esses parâmetros utilizo os métodos da classe It, neste exemplo utilizei o método genérico IsAny, e a definição do Returns também é um pouco diferente neste caso um delegate com três parâmetros do tipo string que retorna um booleano deve ser definido. Os métodos ValidateUser e CreateUser seguem a mesma lógica.

A primeira vista isso tudo pode parecer um pouco complicado, mais pode ter certeza que fazer Mock sem o auxilio de uma framework é muito mais complicado, eu gosto do Moq mais existe outras opções neste link do Wikipedia tem uma lista http://en.wikipedia.org/wiki/List_of_mock_object_frameworks.

Código fonte

Galera é isso até a próxima!

Daniel Fonseca Castro

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Related posts

Add comment


 

  Country flag