【问题标题】:Test doesn't execute method unless I assert on the method's returned value除非我断言方法的返回值,否则测试不会执行方法
【发布时间】:2013-04-26 15:07:09
【问题描述】:

好的,我有一个奇怪的问题。

我在 C# 测试项目中使用 NUnit 和 Moq。我认为你可以忽略 Mock 对象,因为真正的问题在于 UserManager.AddUser() 没有正确执行。

以下代码永远不会到达 UserManager.AddUser() 开始处的断点,因此由于 NullPointerException 将导致 Assertion 失败。

[Test]
enter code here
public void AddUser_NoPassword_GeneratesPassword()
    {
        //assert
        var userRepositoryFake = new Mock<IUserRepository>();
        userRepositoryFake.Setup(x => x.GetUser(It.IsAny<string>(), It.IsAny<bool>())).Returns((User)null);
        userRepositoryFake.Setup(x => x.SaveUser(It.IsAny<User>())).Returns(new Mock<User>().Object);

        var userManager = new UserManager(userRepositoryStub.Object);
        var createUserViewModel = new CreateUserViewModel { Username = "username" };

        //act
        var validationErrors = userManager.AddUser(createUserViewModel);

        //assert
        Assert.IsNotNullOrEmpty(createUserViewModel.Password);
    }

但是,如果我添加这个断言:

        //assert
        Assert.IsEmpty(validationErrors); //new assertion
        Assert.IsNotNullOrEmpty(createUserViewModel.Password);

到达 AddUser() 中的断点,测试成功。 似乎测试根本不执行 AddUser(),除非它的返回值用于某些事情。

【问题讨论】:

  • 您可以将代码发布到 AddUser 吗?
  • @user1770699:AddUser 的返回值是多少?如果是IEnumerable,是否枚举过?

标签: c# asp.net-mvc unit-testing nunit


【解决方案1】:

我的猜测是AddUser 是这样实现的:

public IEnumerable<Error> AddUser(Model model)
{
    // Do some stuff
    if (foo)
    {
        yield return ...;
    }
    if (bar)
    {
        yield return ...;
    } 
    // More stuff
}

换句话说,使用迭代器块。迭代器块是延迟执行的——代码只在第一个元素被请求时开始执行,即使在那个元素被返回时它也会“暂停”。

鉴于这不是一个幂等查询或类似的东西,我建议在内部使用 List&lt;Error&gt; 来实现该方法会更有意义,然后在最后返回。这样,该方法将只执行一次,无论返回值被迭代多少次。这是预期的执行模型,我怀疑。

【讨论】:

  • 非常感谢,我学到了关于收益回报的新知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
  • 2015-07-11
  • 2019-10-10
相关资源
最近更新 更多