我正在测试框架内的服务。
为了初始化服务,我正在使用模拟存储库对象。
ServiceTest.cs
private IRepository _repository;
private IService _service;
private List<Object> _objects;
[TestInitialize]
public void Initialize()
{
_repository = new Mock<IRepository>().Object;
_service = new Service(repository);
_objects = new List<Object>()
{
new Object { Name = "random", ID = 1 },
new Object { Name = "not so random", ID = 1},
new Object { Name = "random", ID = 2 },
new Object { Name = "not so random", ID = 2}
};
//attempt at mocking the repository
_repository.Setup(r => r.GetObjects(It.IsAny<string>(), It.IsAny<int>())).Returns(_objects.Where(o => o.Name == _objects.Name && o.ID == _objects.ID).ToList());
}
[TestMethod]
public void GetObjects_ReturnObjectsList()
{
//Arrange
var name = "random";
//Act
var objects = _service.RetrieveObjects(name, 2);
//Assert
Assert.AreEqual(name, objects.Single().Name);
}
但是,当我测试服务时,我得到ArgumentNullExceptions
。设置为存储库方法的变量调用return null
,并在运行业务逻辑时最终抛出错误。
Service.cs
public List<Objects> RetrieveObjects(string name, int id)
{
var getObjects = repository.GetObjects(name, id); //getObjects return null
DoLogic(getObjects); //ArgumentNullException is thrown here
return getObjects;
}
我已经查找了有关模拟存储库的信息,但似乎我需要设置很多才能进行测试。我想知道这个设置是否值得。
为什么我会ArgumentNullExceptions
?有没有办法测试调用存储库的方法?
答案 0 :(得分:2)
您只需要设置正在测试的内容,以便在您的安排中执行以下操作:
var repository = new Mock<IRepository>();
repository.Setup(x => x.GetObjects(It.IsAny<string>()).Returns("whatever getobjects should be returned, maybe a mock object or string");
var service = new Service(repository.Object());
//Continue your test
答案 1 :(得分:2)
var entity1 = new MyEntity();
var entity2 = new MyEntity();
var entities = new List<MyEntity>{entity1, entity2};
var mockRepository = new Mock<IRespository>();
mockRepository.Setup(r => r.GetObjects("some param")).Returns(entities);
var service = new Service(mockRepository.Object);
service.DoWork("some param");
//continue the test
答案 2 :(得分:2)
您应该单独测试您的SUT(受试者)。不要试图模拟现有的类,只使用接口。这样你就不会依赖其他物体,因为这些物体可能会出现问题。通常,您将无法设置回调并返回用作模拟的现有类。模拟接口允许您控制和预测返回值。
所以在你的特殊情况下,你应该像@ ianaldo21一样提出,我只是改为第一行:
var repository = new Mock<IRepository>();
然后进行设置,并将repository.Object传递给Service。
您应该测试SUT与其他对象的行为和交互,而不是断言SUT的状态。所以你可以这样:
repository.Verify(x => x.GetObjects("test"));
这样,您通常需要更少的设置来进行测试。