【问题标题】:Constructor arguments cannot be passed for interface mocks - MOQ不能为接口模拟传递构造函数参数 - MOQ
【发布时间】:2017-11-04 09:52:11
【问题描述】:

所以我有一个单元测试,它使用一个名为ImpositionCalculatorManager 的类中的方法。在这个类中,我使用依赖注入,因此我可以访问另一个名为 ImpositionCalculatorRepository 的类上的方法。

ImpositionCalculatorManager 看起来像这样:

 public class ImpositionCalculatorManager : IImpositionCalculatorManager {
        private readonly IImpositionCalculatorRepository _impositionCalculatorRepository;
        public ImpositionCalculatorManager(IImpositionCalculatorRepository impositionCalculatorRepository) {
            _impositionCalculatorRepository = impositionCalculatorRepository;
        }
        public ComboBoxItem[] ReturnInkDataSource() {
            return _impositionCalculatorRepository.ReturnInkDataSource();
        }

        public ComboBoxItem[] ReturnCoatingDataSource() {
            return _impositionCalculatorRepository.ReturnCoatingDataSource();
        }
    }
}

在我的单元测试中,我模拟了 ImpositionCalculatorManager 并将模拟版本 ImpositionCalculatorRepository 传递到管理器类的构造函数中。

但是我收到错误Constructor arguments cannot be passed for interface mocks

这是我的单元测试夹具的样子:

 public class ImpositionCalculatorPresenterTestFixture {
        private ImpositionCalculatorPresenter _impositionCalculatorPresenter;
        private readonly SystemVariablesPresenter _systemVariablesPresenter;
        private readonly Mock<IImpositionCalculatorManager> _mockImpositionCalculatorManager;
        private readonly Mock<ISystemVariablesView> _mockSystemVariablesView;
        private readonly Mock<IPrintingDesignManager> _mockPrintingDesignManager;
        private readonly Mock<ISystemVariablesManager> _mockSystemVariablesManager;
        private readonly Mock<IImpositionCalculatorRepository> _mockImpositionCalculatorRepo;
        private Mock<IImpositionFormView> _mockView;

        public ImpositionCalculatorPresenterTestFixture() {
            _mockImpositionCalculatorRepo = new Mock<IImpositionCalculatorRepository>();
//Error occurs on the below line
            _mockImpositionCalculatorManager = new Mock<IImpositionCalculatorManager>(_mockImpositionCalculatorRepo.Object);
            _mockSystemVariablesView = new Mock<ISystemVariablesView>();
            _mockPrintingDesignManager = new Mock<IPrintingDesignManager>();
            _mockSystemVariablesManager = new Mock<ISystemVariablesManager>();
            _systemVariablesPresenter = new SystemVariablesPresenter(_mockSystemVariablesView.Object, _mockSystemVariablesManager.Object);
        }

 [TestMethod]
        public void PopulateInkDataSources_ApplicationOnLoad_InkDataSourcesPopulatedWithDataFromJSON() {
            //Arrange
            SetupImpostionPresenter();
            _mockView.SetupProperty(r => r.InkSideOneDataSource);
            _mockView.SetupProperty(r => r.InkSideTwoDataSource);
            _mockImpositionCalculatorManager.Setup(r => r.ReturnInkDataSource())
                .Returns<ComboBoxItem[]>
                (x => new ComboBoxItem[] {
                        new ComboBoxItem("Test", 1 ),
                        new ComboBoxItem("Test 2", 2)
                });

            //Act
            _mockView.Raise(r => r.FormOnLoad += null, new EventArgs());

            //Assert
            Assert.IsTrue(_mockImpositionCalculatorManager.Object.ReturnInkDataSource()
                == _mockView.Object.InkSideOneDataSource && _mockImpositionCalculatorManager.Object.ReturnInkDataSource()
                == _mockView.Object.InkSideTwoDataSource
                );
        }

private void SetupImpostionPresenter() {
            _mockView = new Mock<IImpositionFormView>();
            _impositionCalculatorPresenter = new ImpositionCalculatorPresenter(_mockView.Object,
            _mockImpositionCalculatorManager.Object, _mockSystemVariablesManager.Object, _systemVariablesPresenter,
            _mockPrintingDesignManager.Object);
        }
    }
}

我看过堆栈溢出,人们说这是因为接口没有构造函数,只有类有,我不应该向构造函数传递任何东西,但是当我删除构造函数参数时从模拟中,我在尝试从管理器设置方法时收到错误Parameter count mismatch

我只想模拟经理,这样我就可以设置一个方法来返回我已经设置的值。

为什么这不起作用?

【问题讨论】:

  • 看起来你在这里缺少模拟声明private readonly Mock&lt;IImpositionCalculatorPresenter&gt; _impositionCalculatorPresenter;
  • 我的演示者不是一个接口,我必须将我的所有方法都虚拟化,我不想这样做。无论如何,这样做会有所作为吗?

标签: c# unit-testing constructor moq


【解决方案1】:

我假设您正在尝试测试具体的 ImpositionCalculatorPresenter 实现?我还假设这个ImpositionCalculatorPresenter 实现预计会响应FormOnLoad 事件。

如果我的假设是正确的,那么您的 _mockImpositionCalculatorManager.Setup(r =&gt; r.ReturnInkDataSource()).Returns&lt;ComboBoxItem[]&gt; (...)) 应该就足够了,并且不需要支持 IImpositionCalculatorRepository 模拟或 impl 或任何东西——您的“我只想模拟经理”的目标似乎已经得到处理通过这种最小起订量设置,它伪造了ImpositionCalculatorPresenter 需要的经理的胆量。

【讨论】:

  • 我正在尝试测试具体的ImpositionCalculatorPresenter,是的,演示者响应了FormOnLoad 事件。我也会认为我的实现是正确的。 manager 方法调用存储库以尝试返回数据。
  • 管理器方法ReturnInkDataSource() 似乎被正确地模拟了,根本不需要涉及存储库。
  • 抱歉,我说的更详细。我希望当您将 manager mock 更改为 _mockImpositionCalculatorManager = new Mock&lt;IImpositionCalculatorManager&gt;(); 时,它会编译。如果您进行此更改,您会得到什么错误?
  • 一旦我这样做,它会调用管理器中的方法,它会抛出异常“参数计数不匹配”
【解决方案2】:

好的,我复制了您的Parameter count mismatch 问题。尝试以下两种更改:

1)(如前所述)在没有任何构造函数且没有任何其他依赖项的情况下创建您的管理器;和

2) 修复 FuncReturnInkDataSource 模拟:更改此:

    _mockImpositionCalculatorManager.Setup(r => r.ReturnInkDataSource())
            .Returns<ComboBoxItem[]>
            (x => new ComboBoxItem[] {
                    new ComboBoxItem("Test", 1 ),
                    new ComboBoxItem("Test 2", 2)
            });

    _mockImpositionCalculatorManager.Setup(r => r.ReturnInkDataSource())
            .Returns(
                () => new ComboBoxItem[] {
                        new ComboBoxItem("Test", 1 ),
                        new ComboBoxItem("Test 2", 2)
                      }
              );

第一个变化是基础 DI/模拟——我们不需要为模拟而模拟。

第二个更改是 Moq 特定的 -- 这是必要的,因为提供给 Returns() 的 lambda 参数必须与 Setup() 中提供的参数匹配 -- 请参阅 Moq + Unit Testing - System.Reflection.TargetParameterCountException: Parameter count mismatch

【讨论】:

  • 啊,我明白了。参数计数不匹配问题根本与存储库无关。那是我嘲笑我的ReturnInkDataSource 接受ComboBoxItem[] 而我没有通过。感谢您的承诺。感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
  • 2014-06-03
  • 2011-11-16
相关资源
最近更新 更多