我在单元测试中遇到问题,我使用moq框架来模拟我的数据库接口以返回数据集。问题是,当我调用BLL方法时,它返回null而不是我设置的对象。 BLL代码是:
public ApplicationsManager(IApplicationsManagerDal applicationsManagerDal)
{
_applicationsManagerDal = applicationsManagerDal ?? throw new Exception("applicationsManagerDAL is null");
}
public IpApplication AddIpApplication(IpApplication ipApplication)
{
try
{
if (Validator.ExecuteValidation(ipApplication, new AddIpApplicationValidationRules()).ValidationFailures != null)
return ipApplication;
ipApplication = _applicationsManagerDal.AddIpApplication(ipApplication);
ipApplication.Status = CommonStatus.OperationOk;
}
catch (BaseException e)
{
ipApplication.Status = e.Status;
}
catch (Exception e)
{
ipApplication.Status = ExceptionHandler.SetStatusForException();
NLogger.LogException("IpApplication Name:" + ipApplication.Name, e);
}
return ipApplication;
}
我设置moq的代码是:
var _mock = new Mock<IApplicationsManagerDal>();
_mock.Setup(a => a.AddIpApplication(new IpApplication
{
Code = new Guid("00000000-B935-4E12-9037-000000000000"),
Name = "APPLICATION_ZERO"
}))
.Returns(() => new IpApplication
{
Code = new Guid("9631E691-B935-4E12-9037-2E874DB15B0D"),
Description = "Test application",
Enabled = true,
Name = "APPLICATION_ZERO",
});
,单元测试是:
[TestMethod(), TestCategory("Unit")]
public void AddIpApplication_ValidRequest_IpApplicationSuccessfullyAdded()
{
// Arrange
_ipApplication = new IpApplication
{
Code = new Guid("9631E691-B935-4E12-9037-2E874DB15B0D"),
Name = "APPLICATION_ZERO"
};
// Act AddIpApplication
_ipApplication = _applicationManager.AddIpApplication(_ipApplication);
Assert.IsTrue(_ipApplication.Code != Guid.Empty);
}
当测试调用时,BLL方法到达了行:
ipApplication = _applicationsManagerDal.AddIpApplication(ipApplication);
它总是返回null。 你能解释一下为什么吗?我如何获得设定值或如何更改单元测试? 谢谢你,抱歉我的英文不好
答案 0 :(得分:1)
如果没有像设置的那样完全调用模拟,它将不会按预期运行。
在您的情况下,您将传递与模拟不同的实例/引用,而不是模拟设置中使用的实例/引用。这将导致mock在调用时返回null(默认行为)。
为了获得更多关于传递参数的灵活性,您可以使用It.IsAny<IpApplication>()
接受任何参数以及Callback
来设置所提供参数的所需属性。这应该允许使用提供的模拟来执行测试中的方法。
_mock
.Setup(_ => _.AddIpApplication(It.IsAny<IpApplication>()))
.Callback((IpApplication arg) => { //<-- use call back to modify the provided parameter
arg.Code = new Guid("9631E691-B935-4E12-9037-2E874DB15B0D");
arg.Description = "Test application";
arg.Enabled = true;
arg.Name = "APPLICATION_ZERO";
})
.Returns((IpApplication arg) => arg); //<-- return provided parameter after Callback
//inject the mock into the subject under test.
_applicationManager = new ApplicationsManager(mock.Object);
参考Moq Quickstart以获取有关如何使用框架的更多详细信息。
答案 1 :(得分:0)
问题是您在安装程序中使用的IpApplication实例引用了与您在执行期间传入的对象不同的对象,因此设置条件不匹配。
_mock.Setup(a => a.AddIpApplication(new IpApplication
{
Code = new Guid("00000000-B935-4E12-9037-000000000000"),
Name = "APPLICATION_ZERO"
}))
您可以覆盖特定类的相等方法,也可以更改安装程序中的逻辑,例如:
_mock.Setup(a => a.AddIpApplication(It.Is<IpApplication>(i => i.Code == expectedGuid && i.Name = expectedString))
如果您不关心确切的值,请使用It.IsAny<IpApplication>()
。