简体   繁体   English

当为 Returns() 提供不同的值时,最小起订量返回相同的结果

[英]Moq Returning Same Result When Supplying Different Values To Returns()

I'm setting up a Mock for various test cases:我正在为各种测试用例设置一个 Mock:

[Test]
[TestCase(0)]
[TestCase(1)]
[TestCase(4)]
public async Task Get_ReturnsAllUsers(int userCount)
{
    // Arrange
    var users = UserRepositoryTests.GenerateUsers(userCount);
    var extensionWrapper = new Mock<IDbConnectionExtensionsWrapper>();
    extensionWrapper
        .Setup(ex => ex.Get<User>(It.IsAny<IDbConnection>(), It.IsAny<IDbTransaction>(), It.IsAny<int>()))
        .Returns(Task.FromResult(users));

    var connection = new Mock<IDbConnection>();
    connection
        .Setup(conn => conn.BeginTransaction())
        .Returns(new Mock<IDbTransaction>().Object);

    var repository = new UserRepository(connection.Object, extensionsWrapper.Object);

    var usersFromRepository = await repository.Get();

    Assert.AreEqual(userCount, usersFromRepository.Count());
}

GenerateUsers looks like GenerateUsers看起来像

private static IEnumerable<User> GenerateUsers(int count)
{
    using var crypto = new RNGCryptoServiceProvider();
    var salt = new byte[16];
    crypto.GetBytes(salt);
    
    var random = new Random();
    var users = new List<User>();
    for (var i = 0; i < count; i++)
    {
        users.Add(new User
        {
            Id = i,
            Username = Convert.ToString(i),
            Salt = salt,
            Hash = salt,
        });
    }

    return users;
}

And the relevant repository code looks like相关的repository代码看起来像

public UserRepository(IDbConnection connection, IDbConnectionExtensionsWrapper wrapper)
{
    this.Connection = connection;
    this.ConnectionWrapper = wrapper;
}

public async Task<IEnumerable<User>> Get()
{
    var users = await this.ConnectionWrapper
        .Get<User>(this.Connection);

    return users;
}

Finally IDbConnectionExtensionsWrapper.Get(...)最后IDbConnectionExtensionsWrapper.Get(...)

public async Task<IEnumerable<T>> Get<T>(
    IDbConnection connection,
    IDbTransaction? transaction = null,
    int? timeout = null)
    where T : class
    => await connection.GetAllAsync<T>(transaction, timeout);

where connection.GetAllAsync belongs to Dapper.Contrib.Extensions .其中connection.GetAllAsync属于Dapper.Contrib.Extensions

The problem I have is that only the first TestCase succeeds.我遇到的问题是只有第一个TestCase成功。 Every call to IDbConnectionExtensionsWrapper.Get returns an empty enumerable, despite the fact that I set the return in each case.每次调用IDbConnectionExtensionsWrapper.Get都会返回一个空的可枚举,尽管我在每种情况下都设置了返回值。

Turns out it was a type mismatch that slipped my eyes.事实证明,这是一种类型不匹配,让我大吃一惊。 Since the signature of IDbConnectionExtensionsWrapper.Get(...) takes an int?由于IDbConnectionExtensionsWrapper.Get(...)的签名需要一个int? and I was setting up the mock with It.IsAny<int>() , there was no suitable call to the method (it was never called).我正在使用It.IsAny<int>()设置模拟,没有合适的方法调用(它从未被调用)。

The correct way to mock the method would be模拟该方法的正确方法是

extensionWrapper
    .Setup(ex => ex.Get<User>(It.IsAny<IDbConnection>(), It.IsAny<IDbTransaction?>(), It.IsAny<int?>()))
    .Returns(Task.FromResult(users));

which ends up making all test cases pass.最终使所有测试用例通过。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM