好的,我有一个奇怪的问题。
我在C#Test项目中使用NUnit和Moq。我认为你可以忽略模拟对象,因为真正的问题在于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(),除非它的返回值用于某些东西。
答案 0 :(得分:5)
我的猜测是AddUser
的实现方式如下:
public IEnumerable<Error> AddUser(Model model)
{
// Do some stuff
if (foo)
{
yield return ...;
}
if (bar)
{
yield return ...;
}
// More stuff
}
换句话说,使用迭代器块。 Iterator块是懒惰地执行的 - 代码只在请求第一个元素时才开始执行,即使这样,它也会在返回该元素时“暂停”。
鉴于这不是一个幂等的查询或类似的东西,我建议在内部使用List<Error>
实现该方法更有意义,然后添加到最后返回。这样,该方法将完全执行一次,但是多次返回值被迭代。这是预期的执行模式,我怀疑。