【问题标题】:Nunit System.InvalidOperationExceptionNunit System.InvalidOperationException
【发布时间】:2020-03-27 14:20:24
【问题描述】:

这是我要测试的方法:

void Update(User user)
{
    if (_userQuery.IsNameExist(user.Guid, (int) user.UserId, user.Name))
        UpdateUser(user);
}

下面的测试类使用方法Update_Test() 应该测试上面的一个。

[TestFixture]
class ModifyuserServiceTest
{
    private IModifyUserService ModifyUserService { get; set; }
    private Mock<IUserQuery> UserQuery { get; set; }
    private Mock<IUserRepository> UserRepository { get; set; }

    [SetUp]
    public void SetUp()
    {
        userQuery = new Mock<IUserQuery>();
        UserRepository = new Mock<IUserRepository>();
        ModifyUserService = new ModifyUserService(userQuery.Object, UserRepository.Object);
    }

    [Test]
    public void Update_Test()
    {
        userQuery.Setup(uow => uow.IsNameExist(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>()))
                .Returns(true);

        ModifyuserService.Update(new User());

        UserRepository.Verify(uow => uow.Add(It.IsAny<User>()), Times.Once);
    }
}

无论出于何种原因,我都会出错:

System.InvalidOperationException : Nullable object must have a value.

当我调试测试方法时,它会在测试方法的这一行引发错误:

if (_userQuery.IsNameExist(user.Guid, (int) user.UserId, user.Name))

当我查看参数值时,有:0, null, null 这似乎很有趣,就像我在userQuery.Setup 中指定的测试方法一样:

It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>()

我什至试过这样:

userQuery.Setup(uow => uow.IsNameExist(999, 33, "whatever"))

然而,同样的错误再次发生并且那里的值显示:0, null, null

这里有什么问题?

更新:

public bool IsNameExist(int guid, int userId, string name)
{
     Parameters = new List<IDbDataParameter>
     {
        Context.CreateParameter("@Guid", guid, DbType.Int64),
        Context.CreateParameter("@userId", userId, DbType.Int64),
        Context.CreateParameter("@Name", name, DbType.String)
     };

    var count = (int)Context.GetScalarValue($"SELECT count(*) FROM {UserTable} WHERE userId=@userId And Guid=@Guid And Name=@Name", CommandType.Text,
                 Parameters.ToArray(), null);

      return count > 0;
}

【问题讨论】:

  • IsNameExist的定义是什么
  • @Nkosi 我发布了,但我认为这不是直接因为这种方法。
  • 包括UpdateUser,因为它是被测方法的一部分
  • @Nkosi 我不知道 - 我什至现在将它标记为虚拟,但它不会改变情况
  • @Nkosi 那时甚至还没有更新

标签: c# unit-testing nunit moq


【解决方案1】:

我刚刚做了一个测试

int? x = null; 
int y = (int)x; //System.InvalidOperationException: 'Nullable object must have a value.'

它在您的测试中失败并显示相同的错误消息

这与 MOQ 设置无关。

您的测试方法正在尝试将null 转换为int,导致运行时错误。

这意味着传递给被测方法的UserId 为空。

您需要为用户 ID 设置一个值,以便可以完成测试。

//...

var user = new User() {
    UserId = 0
};

ModifyuserService.Update(user);

//...

【讨论】:

  • 如果我输入你是对的:ModifyuserService.Update(new User() {UserId = 10);然后测试顺利。但我不明白。 ..只要我在设置中为 IsNameExist 指定行为和值。此方法应采用我在此处指定的值。所以如果我这样做: userQuery.Setup(uow => uow.IsNameExist(11, 20,"whatever")) .Returns(true);应该采用这些值吗?
  • @Arie 不,设置只是告诉模拟程序会发生什么。它在执行时实际上并不传递值。
  • @Arie 您指定模拟“期望”接收哪些值,以便在调用时它会按预期运行。如果您不关心传递了什么值,那是 It.IsAny 的用途。
  • @Nkoise 这就是我所做的(我把初始 IsAny ..)。然而,甚至有什么原因可以将 IsAny 以外的东西像真正的价值一样放在设置中 - 如果你说的值没有被使用?我不明白。
  • @Arie 一旦我意识到你在模拟界面而不是类,我就删除了该评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 2012-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多