Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在具体类中模拟方法_C#_Unit Testing_Mocking - Fatal编程技术网

C# 在具体类中模拟方法

C# 在具体类中模拟方法,c#,unit-testing,mocking,C#,Unit Testing,Mocking,我有一个类,它执行一系列在模型上工作的业务逻辑流程,其中一个是: public virtual void TryToRunProcess(Model model) { var result = RunCheckMethodOne(model) && RunCheckMethodTwo(model); if (result) RunMethodThree(model); } internal virtual bool RunCheckMethodO

我有一个类,它执行一系列在模型上工作的业务逻辑流程,其中一个是:

public virtual void TryToRunProcess(Model model)
{
    var result = RunCheckMethodOne(model) && RunCheckMethodTwo(model);
    if (result)
        RunMethodThree(model);
}

internal virtual bool RunCheckMethodOne(Model model)
{
    ...
}

internal virtual bool RunCheckMethodTwo(Model model)
{
    ...
}

internal virtual void RunMethodThree(Model model)
{
    ...
}
假设模型及其关联的RunCheckMethodOne()和RunCheckMethodTwo()方法足够复杂,足以保证它们自己的单元测试集,我想测试来自RunCheckMethodOne()和RunCheckMethodTwo()的适当响应是否能正确执行RunMethodThree()

我想通过模拟业务逻辑类,设置两个检查方法来返回特定的结果,然后验证是否执行了第三个方法来实现这一点

我的单元测试之一是:

[TestMethod]
public void TryToRunProcessBothCheckMethodsAreTrueShouldExecuteMethodThreeTest()
{
    var model = new Model();

    var mock = new Mock<ModelBusinessLogic>();
    mock.Setup(r => r.RunCheckMethodOne(It.IsAny<Model>())).Returns(true);
    mock.Setup(r => r.RunCheckMethodTwo(It.IsAny<Model>())).Returns(true);
    mock.Setup(r => r.RunMethodThree(It.IsAny<Model>())).Verifiable();

    mock.Object.TryToRunProcess(model);

    mock.Verify(r => r.RunMethodThree(It.IsAny<Model>()), Times.Once());
}
[TestMethod]
public void trytrunprocess这两种检查方法都是正确的,应该执行threetest()方法
{
var模型=新模型();
var mock=new mock();
Setup(r=>r.RunCheckMethodOne(It.IsAny())。返回(true);
Setup(r=>r.RunCheckMethodTwo(It.IsAny())。返回(true);
mock.Setup(r=>r.RunMethodThree(It.IsAny()).Verifiable();
mock.Object.TryToRunProcess(模型);
Verify(r=>r.RunMethodThree(It.IsAny()),Times.Once());
}
现在,对我来说这看起来应该是可行的,但是当我运行这个单元测试时,RunCheckMethodOne()和RunCheckMethodTwo()方法并没有像我预期的那样被模拟;它们实际上在ModelBusinessLogic类中执行,而不是返回在模拟中设置的值

我应该在实现中做些什么来确保我可以将所有业务逻辑方法保持在同一个类中(以便不创建过度设计的解决方案),并且仍然能够在业务逻辑类中模拟方法以在其他方法中执行特定场景


我正在使用.Net Framework 4.5和Moq 4.0.0.0。

您需要做两件事:

  • mock.CallBase=true
  • 将内部方法公开或改为受保护的内部方法(显然不太理想)
<>我也认为,如果你说,有足够的复杂性来保证个人测试的话,你应该考虑把你的课分解掉。对我来说,这听起来不像是过度工程

编辑

您也可以添加

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

如果你的类不是强名称的话。有关更多信息,请参阅。

mock.Callbase=true-help吗?我也尝试过使用该标志,但似乎没有任何帮助。根据针对Moq的intellisense帮助,当没有设置时,CallBase属性默认为基本虚拟实现。这看起来对我没有帮助,因为我已经准备好了要显式使用的设置,而不是ModelBusinessLogic.或protected internal中的底层实现。谢谢James!将受保护的内部关键字添加到RunCheckMethodOne()、RunCheckMethodTwo()和RunMethodThree()的方法签名中似乎就可以做到这一点。我不需要设置mock.CallBase=true来获得我想要的行为。我的下一个问题(纯粹为了学术上的安心)是,为什么受保护的内部方法在这种情况下表现出与内部方法不同的行为?“受保护的内部”意味着成员既是受保护的又是内部的——它既有性质,又没有两者的“交叉点”。添加受保护使成员可以在派生类型中访问,即使是在另一个程序集中创建的成员也是如此。添加了
InternalsVisibleTo
替代项