如何忽略Moq VerifySet()表达式中的空格?

时间:2010-11-06 04:24:14

标签: c# unit-testing mocking moq

我想验证字符串是否设置为Moq对象中的特定值。

我创建了一个小型控制台应用程序来模拟我想要做的事情。

using System;
using Moq;

namespace MoqVerifySet
{
    public interface MyInterface
    {
        string MyValue { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Mock<MyInterface> mockMyInterface = new Mock<MyInterface>();
            var myI = mockMyInterface.Object;
            myI.MyValue = @"hello 
                            world.
                            Please ignore
                            the whitespace";

            try
            {
                mockMyInterface.VerifySet(i => i.MyValue = "hello world. Please ignore the whitespace");
                Console.WriteLine("Success");
            }
            catch(Exception ex)
            {
                Console.WriteLine("Error : {0}", ex.Message);
            }

            Console.WriteLine("\n\nPress any key to exit...");
            Console.ReadKey();
        }
    }
}

所以,我以为我可以创建一个小方法

public static string PrepSqlForComparison(string sql)
{
    Regex re = new Regex(@"\s+");
    return re.Replace(sql, " ").Trim().ToLower();
}

并改变

mockMyInterface.VerifySet(i => i.MyValue = "hello world. Please ignore the whitespace");

mockMyInterface.VerifySet(i => PrepSqlForComparison(i.MyValue) = "hello world. Please ignore the whitespace");

但由于表达式中的运算符是赋值,而不是等于。

,因此无法编译

因此,如果我不能这样做,我如何在忽略大小写,空格和其他格式的同时进行验证?

2 个答案:

答案 0 :(得分:4)

如果您不需要VerifySet的功能(如果您只关心最后一个设置值),您可以在模拟对象中设置MyValue属性,只需通过调用回显最后一个设置值:

mockMyInterface.SetupProperty(f => f.MyValue);

然后你可以执行比较/相等检查,忽略空格和换行符。我创建了一个自定义StringComparer来将这个逻辑封装在我的测试中:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace MoqVerifySet
{
public interface MyInterface
{
    string MyValue { get; set; }
}

internal class Program
{
    private static void Main(string[] args)
    {
        var mockMyInterface = new Mock<MyInterface>();
        mockMyInterface.SetupProperty(f => f.MyValue);

        MyInterface myI = mockMyInterface.Object;
        myI.MyValue = @"hello 
                        world.
                        Please ignore
                        the whitespace";
        try
        {
            var comparer = new CompareWithoutWhitespace(StringComparison.CurrentCultureIgnoreCase);
            Assert.IsTrue(comparer.Equals(myI.MyValue, "hello world. Please ignore the whitespace"));
            Console.WriteLine("Success");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error : {0}", ex.Message);
        }

        Console.WriteLine("\n\nPress any key to exit...");
        Console.ReadKey();
    }
}

internal class CompareWithoutWhitespace : StringComparer
{
    private readonly StringComparison _stringComparison;

    public CompareWithoutWhitespace(StringComparison stringComparison)
    {
        _stringComparison = stringComparison;
    }

    public override int Compare(string x, string y)
    {
        return String.Compare(RemoveWhitespace(x), RemoveWhitespace(y), _stringComparison);
    }

    public override bool Equals(string x, string y)
    {
        return String.Equals(RemoveWhitespace(x), RemoveWhitespace(y), _stringComparison);
    }

    public override int GetHashCode(string obj)
    {
        return RemoveWhitespace(obj).GetHashCode();
    }

    private static string RemoveWhitespace(string input)
    {
        if (string.IsNullOrEmpty(input)) return input;
        input = input.Replace(Environment.NewLine, "");
        return input.Replace(" ", "");
    }
}
}

答案 1 :(得分:1)

你的空白问题与Mock无关,你的myI.MyValue正在使用verbatim string literal

该行:

myI.MyValue = @"hello world.
                Please ignore
                the whitespace";

注意最后两行第一个字母左边的所有空格。相当于写作:

myI.MyValue = @"hello world.                            Please ignore                            the whitespace";