4

私は次のリポジトリを持っています:

interface IReportingRepository where T: Report
{
     IEnumerable<T> GetReports<T>(object constraints);
}

そして私はこのリポジトリへの呼び出しを次のようにモックアウトしようとしています:

var reportingRepostory = new Mock<IReportingRepository>();
                       reportingRepostory.Setup(x => 
                       x.GetReports<ServiceReport (Moq.It.IsAny<object>())).
                       Returns(new List<ServiceReport>(){Report1, Report2});

ただし、渡す代わりに

Moq.It.IsAny<object>()

匿名タイプを渡したい

new {Activated = true, Enabled = true}

正しい匿名タイプが使用されるという期待を設定できるようにします。

4

2 に答える 2

4

少し反射の助けを借りてカスタムマッチャーを使用することができます:

var reportingRepostory = new Mock<IReportingRepository>();
reportingRepostory
    .Setup(x => x.GetReports<ServiceReport>(HasProperties()))
    .Returns(new List<ServiceReport>(){Report1, Report2});

HasPropertiesメソッドが次のように実装されている場合:

private object HasProperties()
{
    return Match.Create(
        (object o)  =>
        {
            var properties = o.GetType().GetProperties();
            return properties.Any(p => p.Name == "Available")
                && properties.Any(p => p.Name == "Enabled");
        });
}    
于 2012-04-24T14:29:44.067 に答える
3

元のソリューションでは検出されないいくつかの実装バグ:

new {Activated = true, Enabled = false}
new {Activated = true, Enabled = true, Extra = "I'm not meant to be here!"}
new {Activated = true, Enabled = "true"}

IReportingRepository GetReportsメソッドの実装の複雑さによっては、匿名型のプロパティ値と値型が期待どおりであり、期待されるプロパティのみが正確に存在することを確認することを検討する価値がある場合があります。

var reportingRepostory = new Mock<IReportingRepository>();
reportingRepostory
    .Setup(x => x.GetReports<ServiceReport>(IsAnonymousType(new {Activated = true, Enabled = true})))
    .Returns(new List<ServiceReport>(){Report1, Report2});

IsAnonymousTypeメソッドは次のとおりです。

private static object IsAnonymousType(object expected)
{
    return Match.Create(
        (object actual) =>
        {
            if (expected == null)
            {
                if (actual == null)
                    return true;
                else
                    return false;
            }
            else if (actual == null)
                return false;

            var expectedPropertyNames = expected.GetType().GetProperties().Select(x => x.Name);
            var expectedPropertyValues = expected.GetType().GetProperties().Select(x => x.GetValue(expected, null));
            var actualPropertyNames = actual.GetType().GetProperties().Select(x => x.Name);
            var actualPropertyValues = actual.GetType().GetProperties().Select(x => x.GetValue(actual, null));

            return expectedPropertyNames.SequenceEqual(actualPropertyNames)
                && expectedPropertyValues.SequenceEqual(actualPropertyValues);
        });
}
于 2013-06-24T09:03:17.503 に答える