【问题标题】:setup function to return result of same function that is being setup设置函数返回正在设置的相同函数的结果
【发布时间】:2016-09-08 17:39:14
【问题描述】:

我正在单元测试中设置一个函数,并希望返回正在设置的相同函数的结果。

界面是这样的。

 public interface ICommonServices
{
    int[] GetIntArray();
    int AddOne(int a);
}

接口是这样实现的。

  public int AddOne(int a)
    {
        return a + 1;
    }
    public int[] GetIntArray()
    {
        int[] x = { 1, 2, 3, 4 };
        return x;
    }

被测服务(ObservationService)有一个功能需要测试。

public string SomeCalculation()
    {
        var intArray = _commonServices.GetIntArray();
        List<int> result = intArray.Select(x => _commonServices.AddOne(x)).ToList();
        //Do Something With result.
        return "Done";
    }

_commonServices 使用 DI 进行注入。

我的单元测试看起来像这样

   [Test]
    public void Some_Test()
    {
        int[] a = { 5, 6, 7, 8 };
        using (var mock = AutoMock.GetLoose())
        {
            // Arrange          
            mock.Mock<ICommonServices>().Setup(x => x.GetIntArray()).Returns(a);
            mock.Mock<ICommonServices>().Setup(x => x.AddOne(It.IsAny<int>())).Returns(/* what to do here AddOne(x)   */);
            var sut = mock.Create<ObservationService>();
            // Act
            var res = sut.SomeCalculation();
            // Assert
            Assert.AreEqual("Done", res);
        }
    }

我正在尝试设置“AddOne”函数来返回它自己的结果。

【问题讨论】:

  • 为什么要模拟只有a + 1 的东西?根本没有必要模拟它。
  • 这只是一个例子。在实际代码中发生了更多事情。
  • 那么您可能必须简化测试,以便测试一些更具体的情况并准确返回与该特定测试用例对应的函数 AddOne 的值?
  • 测试的条件是什么?你能用这个命名模式吗? UnitOfWork_StateUnderTest_ExpectedBehavior.
  • 你的 sut 不应该被嘲笑。你嘲笑 sut 的依赖关系

标签: c# unit-testing nunit moq autofac


【解决方案1】:

希望我理解正确。

你可以这样做:

mock.Mock<ICommonServices>().Setup(x => x.AddOne(It.IsAny<int>())).Returns( (int a) =>
                                                                        {
                                                                            return a + 1;
                                                                        });

如何复用AddOne()方法:

  1. 将您的AddOne() 声明为static
public class CommonServices : ICommonServices
{
    public static int AddOne(int a)
    {
        return a + 1;
    }
}
  1. 现在您可以在模型中使用 static 方法
mock.Mock<ICommonServices>().Setup(x => x.AddOne(It.IsAny<int>())).Returns( (int a) =>
                                                                            {
                                                                                return CommonServices.AddOne(a);
                                                                            });

【讨论】:

  • 但我必须再次编写 a+1 函数。我不能使用相同的功能吗?
  • 当然可以,但是您需要将AddOne 方法声明为静态。这种情况请参考这个帖子:Mock a Method with Moq and make moq.Object available there
  • 但是我正在更改我的代码以适应我的测试,这违反了单元测试概念。不是吗?
【解决方案2】:

解决方案是最小起订量 CommonService

   var cs = mock.Create<CommonServices>();

并使用它作为回报

mock.Mock<ICommonServices>().Setup(x => x.AddOne(It.IsAny<int>())).Returns( (int a) =>
                                                                        {
                                                                            return cs.AddOne(a);
                                                                        });

【讨论】:

    猜你喜欢
    • 2012-02-29
    • 1970-01-01
    • 2015-10-20
    • 2020-08-31
    • 2014-01-17
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 2020-04-05
    相关资源
    最近更新 更多