【问题标题】:C# Moq framework return null reference not correct objectC# Moq 框架返回空引用不正确的对象
【发布时间】:2018-01-12 15:47:45
【问题描述】:

我在单元测试中遇到问题,我使用 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;
    }

我设置起订量的代码是:

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。 你能解释一下为什么吗?如何获得设定值或如何更改单元测试? 谢谢你,对不起我的英语不好

【问题讨论】:

  • 传递的实例/引用与模拟中设置的不同。
  • 使用It.IsAny&lt;IpApplication&gt;()Callback 来设置所需的属性。
  • 请提供实际代码 - 到目前为止,没有迹象表明您甚至在任何地方使用 _mock。很混乱。如果您需要帮助了解帖子中需要包含哪些代码,请阅读 minimal reproducible example 指南。

标签: c# unit-testing mocking moq


【解决方案1】:

当一个模拟没有完全按照它的设置被调用时,它的行为就不会像预期的那样。

在您的情况下,您传递的模拟实例/引用与模拟设置中使用的不同。这将导致模拟在调用时返回 null(默认行为)。

为了在传递参数方面获得更大的灵活性,您可以使用It.IsAny&lt;IpApplication&gt;() 接受任何参数以及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 以获取有关如何使用该框架的更多详细信息。

【讨论】:

  • 我严重怀疑更改 _mock 的设置方式是否会有所帮助,因为它根本没有在 OP 的代码中使用。
【解决方案2】:

问题是您在设置中使用的 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&lt;IpApplication&gt;()

【讨论】:

    猜你喜欢
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    相关资源
    最近更新 更多