C# xUnit测试将模型添加到列表失败
我正在使用xUnit测试我的项目。我有一个测试,检查C# xUnit测试将模型添加到列表失败,c#,asp.net,unit-testing,xunit,nancy,C#,Asp.net,Unit Testing,Xunit,Nancy,我正在使用xUnit测试我的项目。我有一个测试,检查用户是否已添加到用户的列表,如下所示: private readonly IJsonService _jsonService; private readonly IUserService _userService; [Fact] public void Add_User_To_User_List() { //Given _userService = new UserService(_jsonSe
用户
是否已添加到用户的列表
,如下所示:
private readonly IJsonService _jsonService;
private readonly IUserService _userService;
[Fact]
public void Add_User_To_User_List()
{
//Given
_userService = new UserService(_jsonService, _guidService);
_jsonService = Substitute.For<IJsonService>();
var _fakeUserJsonFile = "Users.json";
var _fakeNewUser = new User()
{
ID = new Guid(),
FirstName = "Denis",
LastName = "Menis"
};
var _fakeUserList = new List<User>
{
new User()
{
ID = new Guid(),
FirstName = "Paddy",
LastName = "Halle"
},
new User()
{
ID = new Guid(),
FirstName = "Job",
LastName = "Blogs"
}
};
var _fakeUpdatedUserList = new List<User>
{
new User()
{
ID = new Guid(),
FirstName = "Paddy",
LastName = "Halle"
},
new User()
{
ID = new Guid(),
FirstName = "Job",
LastName = "Blogs"
},
new User()
{
ID = new Guid(),
FirstName = "Denis",
LastName = "Menis"
}
};
_jsonService.DeserializeObject<User>(_fakeUserJsonFile).Returns(_fakeUserList);
_jsonService.SerializeObject(_fakeUserJsonFile, _fakeUpdatedUserList).Returns(true);
//When
var result = _userService.AddUser(_fakeNewUser);
//Then
Assert.Contains(_fakeNewUser, _fakeUpdatedUserList);
}
GetUser方法:
public List<User> GetUsers()
{
return _jsonService.DeserializeObject<User>(_fileName).ToList();
}
当我运行测试时,var serializeObject=\u jsonService.serializeObject(\u fileName,userList)来自AddUser
方法的code>每次都返回false
我认为它这样做是因为即使它是与预期结果相同的数据,但在内存中它是对相同数据的不同引用
有人能帮我吗?我希望它返回相同的引用数据。如果我不是很清楚,我可以详细说明。谢谢您完全正确,问题的根源在于\u fakeUserList
和\u fakeupdateuserlist
引用了两个完全不同的对象。您已将\u jsonService.SerializeObject
配置为在传递对\u fakeUpdateUserList
的引用时返回true
——但实际上您传递的是对(修改的)\u fakeUserList
的引用
基本上,\u fakeUpdateUserList
完全没有必要。您可以关注\u fakeUserList
,因为这是提供给SUT的对象(大概是通过反序列化对象
)
例如:
[Fact]
public void Add_User_To_User_List()
{
//Given
_userService = new UserService(_jsonService, _guidService);
_jsonService = Substitute.For<IJsonService>();
var _fakeUserJsonFile = "Users.json";
var _fakeNewUser = new User()
{
ID = new Guid(),
FirstName = "Denis",
LastName = "Menis"
};
var _fakeUserList = new List<User>
{
new User()
{
ID = new Guid(),
FirstName = "Paddy",
LastName = "Halle"
},
new User()
{
ID = new Guid(),
FirstName = "Job",
LastName = "Blogs"
}
};
_jsonService.DeserializeObject<User>(_fakeUserJsonFile).Returns(_fakeUserList);
_jsonService.SerializeObject(_fakeUserJsonFile, _fakeUserList).Returns(true); // Match the original _fakeUserList, since that is what gets passed in by the implementation
//When
var result = _userService.AddUser(_fakeNewUser);
//Then
Assert.Contains(_fakeNewUser, _fakeUserList); // Verify that the provided _fakeUserList has been modified
}
// Match any filename (unless you have a way of getting _fakeUserJsonFile into the SUT)
// Match any list, as long as it contains the new user
_jsonService.SerializeObject(Arg.Any<string>(), Arg.Is<List<User>>(list => list.Contains(_fakeNewUser))).Returns(true);
//When
var result = _userService.AddUser(_fakeNewUser);
//Then
Assert.IsTrue(result); // Only returns true if the mock object is invoked as expected
// There is no way to verify the following assertion, because the test has no way of accessing the "updated" list
//Assert.Contains(_fakeNewUser, _fakeUserList);
你能显示一些设置代码吗?特别是,将\u fileName
链接到\u fakeUserJsonFile
,并将userList
链接到\u fakeUpdatedUserList
?@Lilshieste我已更新代码以显示数据谢谢!还有一个问题:你在使用什么样的模拟框架?替代品?(即,\u jsonService
的类型是什么?)我正在使用NSubstitute yes。我将更新\u jsonService
代码,它只是一个读取和写入通用json文件的类,难道你不能同时使用_fakeUserList和drop _fakeUpdateUserList吗?嗨,谢谢你的回复,即使我只使用上面的代码,它仍然无法序列化用户,这就是为什么我认为它得到了相同的变量(即\u fakeUserJsonFile
和\u fakeUserList
)作为memeory中的不同引用,如果这使senseYes生效,您需要确保\u fileName
引用的对象与\u fakeUserJsonFile
引用的对象相同。您还需要确保GetUsers
返回由反序列化对象
返回的列表(即,不是它的副本)。如果您发布GetUsers
(以及设置\u fileName
)的代码,我们可以验证引用是否相同。我添加了getuser方法和反序列化方法问题在于反序列化对象
方法:当您调用ToList()时
,将使用IEnumerable
的内容创建一个新列表(这就是返回的列表与\u fakeUserList
不同的原因)。是否有任何方法来测试它?或者我必须将方法更改为列表
而不是IEnumerale
?
public class FileSystem : IFileSystem
{
public void WriteAllText(string path, string contents)
{
File.WriteAllText(path, contents);
}
public string ReadAllText(string path)
{
return File.ReadAllText(path);
}
}
[Fact]
public void Add_User_To_User_List()
{
//Given
_userService = new UserService(_jsonService, _guidService);
_jsonService = Substitute.For<IJsonService>();
var _fakeUserJsonFile = "Users.json";
var _fakeNewUser = new User()
{
ID = new Guid(),
FirstName = "Denis",
LastName = "Menis"
};
var _fakeUserList = new List<User>
{
new User()
{
ID = new Guid(),
FirstName = "Paddy",
LastName = "Halle"
},
new User()
{
ID = new Guid(),
FirstName = "Job",
LastName = "Blogs"
}
};
_jsonService.DeserializeObject<User>(_fakeUserJsonFile).Returns(_fakeUserList);
_jsonService.SerializeObject(_fakeUserJsonFile, _fakeUserList).Returns(true); // Match the original _fakeUserList, since that is what gets passed in by the implementation
//When
var result = _userService.AddUser(_fakeNewUser);
//Then
Assert.Contains(_fakeNewUser, _fakeUserList); // Verify that the provided _fakeUserList has been modified
}
// Match any filename (unless you have a way of getting _fakeUserJsonFile into the SUT)
// Match any list, as long as it contains the new user
_jsonService.SerializeObject(Arg.Any<string>(), Arg.Is<List<User>>(list => list.Contains(_fakeNewUser))).Returns(true);
//When
var result = _userService.AddUser(_fakeNewUser);
//Then
Assert.IsTrue(result); // Only returns true if the mock object is invoked as expected
// There is no way to verify the following assertion, because the test has no way of accessing the "updated" list
//Assert.Contains(_fakeNewUser, _fakeUserList);