【问题标题】:MOQ - setting up a method based on argument values (multiple arguments)MOQ - 根据参数值(多个参数)设置方法
【发布时间】:2011-05-04 02:46:37
【问题描述】:

我有一个定义为

的接口
interface IMath
{
 AddNumbersBetween(int lowerVal, int upperVal);
}

我可以为上述设置一个基本的起订量,如下所示:

Mock<IMath> mock = new Mock<IMath>();    
mock.Setup(m => m.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>()));

叫它

mock.Object.AddNumbersBetween(1,4);

然后验证它是否被调用

mock.Verify(m => m.AddNumbersBetween(1,4), Times.AtleastOnce());

我不知道如何设置 AddNumbersBetween 方法,如果 upperVal 低于 lowerVal 则会引发异常

mock.Object.AddNumbersBetween(4,1);//should throw an exception

基本上是在寻找类似的东西:

mock.Setup(foo => foo.AddNumbersBetween("arg1 is higher than arg2")).Throws<ArgumentException>();

【问题讨论】:

  • 我建议简单地使用回调实现抛出异常的逻辑,因为这使您可以完全访问这两个参数。据我所知,参数匹配子句只能执行基于单个参数的逻辑。

标签: c# unit-testing moq


【解决方案1】:

我知道这已经有一年了,但我找到了一种至少在最新版本的 Moq 中使用多个参数的方法:

mock.Setup(x => x.Method(It.IsAny<int>(), It.IsAny<int>()))
    .Returns<int, int>((a, b) => a < b);

【讨论】:

  • @NightOwl888 不...当你只有一个返回语句时,你不需要。
【解决方案2】:

对于单参数方法,最简洁的方法是:

mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>();
...
public string IsLarge() 
{ 
  return Match<string>.Create(s => !String.IsNullOrEmpty(s) && s.Length > 100);
}

如果方法有多个参数,则不能应用。仍然可以使用一种“解决方法”来模仿您想要实现的目标:

/// <summary>
/// Tests if a moq can send an exception with argument checking
///</summary>
[TestMethod]
public void TestException()
{
    Mock<IMath> mock = new Mock<IMath>();
    mock.Setup(m => m.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>()));

    mock.Setup(foo => foo.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>()))
        .Callback<int, int>((i, j) => CheckArgs(i, j));

    try
    {
        mock.Object.AddNumbersBetween(1, 2);
    }
    catch (Exception ex)
    {
        // Will not enter
        Console.WriteLine("Exception raised: {0}", ex);
    }
    try
    {
        mock.Object.AddNumbersBetween(2, 1);
    }
    catch (Exception ex)
    {
        // Will enter here, exception raised
        Console.WriteLine("Exception raised: {0}", ex);
    }
}

private bool CheckArgs(int i, int j)
{
    if( i > j)
        throw new ArgumentException();
    return true;
}

【讨论】:

  • 这仅适用于单个参数,而不适用于多个参数
  • 我的错......还有另一种处理方式,如果参数未通过验证,回调将引发异常。我已经用这种方法编辑了我的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 2012-09-22
  • 1970-01-01
  • 2022-10-08
  • 1970-01-01
相关资源
最近更新 更多