无法理解如何测试某些东西

时间:2012-01-23 00:23:40

标签: c# unit-testing moq

不确定我需要在这做什么。我有私有方法,使数据库调用反向查看值,然后将值返回给调用者。我看过Moq,但我不确定这是我需要的。

我的一个方法的例子是:

    private bool ClientIdMatchesUserId(int userId, Guid clientId, out string message)
    {
        bool idsMatch;

        const string sql = "sql goes here";

        int result = (int)SqlHelper.ExecuteScalar(Connection, CommandType.Text, sql);
        if (result != 1)
        {
            idsMatch = false;
            message = "ClientId does not match.";
        }
        else
        {
            idsMatch = true;
            message = "ClientId matches.";
        }

        return idsMatch;
    }

让我感到困惑的是1)我有一个私人方法,2)它有参数。

Moq是我需要的吗?我是否需要创建具有已知值的测试数据库?

我应该补充一点,我是测试的新手,可以使用我能得到的所有建议;)

2 个答案:

答案 0 :(得分:3)

为了对类进行单元测试,您需要将数据库访问与业务逻辑分开。此时,您可以模拟依赖项并通过其公共接口测试该类。

这是一个如何做到这一点的例子。

public class User
{
    // properties map to columns
    // Consider using NHibernate, Entity Framework, etc.
}

// ALL database access goes through interface implementations.
public interface IUserRepository
{
    // One of several options - TryParse pattern
    bool TryGetById(int userId, out User user);
}

public class SomeBusinessLogic
{
    public SomeBusinessLogic(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public string ValidateClient(int userId)
    {
        // Probably more logic here.
        string message;
        bool result = ClientIdMatchesUserId(userId, out message);

        if (result)
        {
            return string.Empty;
        }

        return message;
    }

    private bool ClientIdMatchesUserId(int userId, out string message)
    {
        User user;
        bool found = _userRepository.TryGetById(userId, out user);

        message =
            found
            ? "ClientId matches."
            : "ClientId does not match.";

        return found;
    }

    private readonly IUserRepository _userRepository;
}

您的测试看起来像这样:

[Test]
public void ValidateClient_WhenValid_ReturnsEmptyString()
{
    // Arrange
    const int UserId = 1234;
    var mockRepo = new Mock<IUserRepository>();
    var user = new User();
    mockRepo.Setup(x => x.TryGetById(UserId, out user)).Returns(true);
    var sut = new SomeBusinessLogic(mockRepo.Object);

    // Act
    string result = sut.ValidateClient(UserId);

    // Assert
    Assert.That(result, Is.EqualTo(string.Empty));
}

[Test]
public void ValidateClient_WhenInvalid_ReturnsMessage()
{
    // Arrange
    var mockRepo = new Mock<IUserRepository>();
    var sut = new SomeBusinessLogic(mockRepo.Object);

    // Act
    string result = sut.ValidateClient(1234);

    // Assert
    Assert.That(result, Is.EqualTo("ClientId does not match."));
}

我建议您阅读The Art of Unit Testing with Examples in .NET以便更好地了解这一点。这是一个复杂的话题。

答案 1 :(得分:0)

我看看摩尔人。 http://research.microsoft.com/en-us/projects/pex/downloads.aspx

Moq用于模拟接口依赖关系或依赖关系,它们是具有默认构造函数和虚方法的公共类。 Moles允许你模拟任何东西,专门用于模拟外部依赖项,如数据库,文件等。