Cómo burlarse y realizar pruebas unitarias correctamente

Básicamente estoy tratando de enseñarme a mí mismo cómo codificar y quiero seguir buenas prácticas. Hay beneficios obvios para las pruebas unitarias. También hay mucho fanatismo cuando se trata de pruebas unitarias y prefiero un enfoque mucho más pragmático para la codificación y la vida en general. Como contexto, actualmente estoy escribiendo mi primera aplicación "real", que es el omnipresente motor de blog que usa asp.net MVC. Estoy siguiendo libremente la arquitectura MVC Storefront con mis propios ajustes. Como tal, esta es mi primera incursión real en burlarse de objetos. Pondré el código de ejemplo al final de la pregunta.

Agradecería cualquier conocimiento o recursos externos que pudiera utilizar para aumentar mi comprensión de los fundamentos de las pruebas y las burlas. Los recursos que he encontrado en la red generalmente están orientados al "cómo" de burlarse y necesito una mejor comprensión del dónde, por qué y cuándo de burlarse. Si este no es el mejor lugar para hacer esta pregunta, indíqueme un lugar mejor.

Estoy tratando de entender el valor que obtengo de las siguientes pruebas. El UserService depende del IUserRepository. El valor de la capa de servicio es separar su lógica de su almacenamiento de datos, pero en este caso la mayoría de las llamadas de UserService se pasan directamente a IUserRepository. El hecho de que no haya mucha lógica real para probar también podría ser la fuente de mis preocupaciones. Tengo las siguientes preocupaciones.

Parece que el código solo está probando que el marco burlón está funcionando.Para burlar las dependencias, hace que mis pruebas tengan demasiado conocimiento de la implementación de IUserRepository. ¿Es este un mal necesario?¿Qué valor estoy obteniendo realmente de estas pruebas? Es la simplicidad del servicio bajo prueba lo que me hace dudar del valor de estas pruebas.

Estoy usando NUnit y Rhino.Mocks, pero debería ser bastante obvio lo que estoy tratando de lograr.

    [SetUp]
    public void Setup()
    {
        userRepo = MockRepository.GenerateMock<IUserRepository>();
        userSvc = new UserService(userRepo);
        theUser = new User
        {
            ID = null,
            UserName = "http://joe.myopenid.com",
            EmailAddress = "[email protected]",
            DisplayName = "Joe Blow",
            Website = "http://joeblow.com"
        };
    }

    [Test]
    public void UserService_can_create_a_new_user()
    {
        // Arrange
        userRepo.Expect(repo => repo.CreateUser(theUser)).Return(true);

        // Act
        bool result = userSvc.CreateUser(theUser);

        // Assert
        userRepo.VerifyAllExpectations();
        Assert.That(result, Is.True, 
          "UserService.CreateUser(user) failed when it should have succeeded");
    }

    [Test]
    public void UserService_can_not_create_an_existing_user()
    {
        // Arrange
        userRepo.Stub(repo => repo.IsExistingUser(theUser)).Return(true);
        userRepo.Expect(repo => repo.CreateUser(theUser)).Return(false);
        // Act
        bool result = userSvc.CreateUser(theUser);

        // Assert
        userRepo.VerifyAllExpectations();
        Assert.That(result, Is.False, 
            "UserService.CreateUser() allowed multiple copies of same user to be created");
    }

Respuestas a la pregunta(4)

Su respuesta a la pregunta