C# 使用Rhino Mock报告调用的函数

C# 使用Rhino Mock报告调用的函数,c#,rhino-mocks,C#,Rhino Mocks,我有一个失败的测试用例,它依赖于外部模块。 我想使用Rhino Mock生成关于被调用函数的报告 我创建了一个简单的示例来说明我的问题: using NUnit.Framework; using Rhino.Mocks; using System; namespace StackOverflow_namespace { public interface IUsefulService { object HiddenAmongManyCalls(); }

我有一个失败的测试用例,它依赖于外部模块。 我想使用Rhino Mock生成关于被调用函数的报告

我创建了一个简单的示例来说明我的问题:

using NUnit.Framework;
using Rhino.Mocks;
using System;

namespace StackOverflow_namespace
{
    public interface IUsefulService
    {
        object HiddenAmongManyCalls();
    }

    public class ThirdPartyBase
    {
        private int a = 42;

        public ThirdPartyBase(IUsefulService service)
        {
            object liveFastDieYoung = service.HiddenAmongManyCalls();
            liveFastDieYoung.Equals(a);
        }
    }

    public class MyParty : ThirdPartyBase
    {
        public MyParty(IUsefulService service) : base(service)
        {

        }
    }


    [TestFixture]
    class StackOverflow
    {
        [Test]
        public void Hypothetical()
        {
            IUsefulService service = MockRepository.GenerateMock<IUsefulService>();

            try
            {
                var party = new MyParty(service);
            }
            catch(Exception e)
            {
                string[] calls = MagicallyGetTheCallsThatWereMadeToTheMock();
                foreach(var call in calls)
                {
                    //with my visual studio testrunner for nunit 3 I can investigate stored console output
                    Console.WriteLine(call);
                }
                Assert.Fail("Excpexted no exception but was '" + e.GetType().Name + "': " + e.Message);
            }
        }

        private string[] MagicallyGetTheCallsThatWereMadeToTheMock()
        {
            return new[]
            {
                "This is where I am lost, I do not know how to get the calls from the repository."
            };
        }
    }
}

我能够使用反射来获得我想要的输出。 下面是测试失败且输出包含所有方法调用的最小示例

using NUnit.Framework;
using Rhino.Mocks;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace StackOverflow_namespace
{
    public interface IUsefulService
    {
        object HiddenAmongManyCalls();
        string TestCall2(string arg1, int arg2);
        string FULLACCESS { get; set; }
        string READONLY { get; }
    }

    public class ThirdPartyBase
    {
        private int a = 42;

        public ThirdPartyBase(IUsefulService service)
        {
            service.TestCall2("callA", 1);
            service.TestCall2("callB", 1);
            object liveFastDieYoung = service.HiddenAmongManyCalls();
            service.TestCall2("callA", 2);
            service.TestCall2("callB", 2);
            var a = service.FULLACCESS;
            var b = service.READONLY;
            service.FULLACCESS = "some";
            liveFastDieYoung.Equals(a);
        }
    }

    public class MyParty : ThirdPartyBase
    {
        public MyParty(IUsefulService service) : base(service)
        {

        }
    }


    [TestFixture]
    class StackOverflow
    {
        [Test]
        public void Hypothetical()
        {
            IUsefulService service = MockRepository.GenerateMock<IUsefulService>();

            try
            {
                var party = new MyParty(service);
            }
            catch (Exception e)
            {
                var calls = GetCallsList(service);
                foreach (var call in calls)
                {
                    //with my visual studio testrunner for nunit 3 I can investigate stored console output
                    Console.WriteLine(call);
                }
                Assert.Fail("Excpexted no exception but was '" + e.GetType().Name + "': " + e.Message);
            }
        }

        private IEnumerable<string> GetCallsList<Interface>(Interface rhinomock)
        {
            Type interfaceType = typeof(Interface);
            List<MethodInfo> interfaceMethodInfos = new List<MethodInfo>();
            List<string> returnInfos = new List<string>();
            StringBuilder callbuilder = new StringBuilder();

            foreach (var property in interfaceType.GetProperties())
            {
                AddMethodInfoIfValid(interfaceMethodInfos, property.GetGetMethod());
                AddMethodInfoIfValid(interfaceMethodInfos, property.GetSetMethod());
            }
            foreach (var method in interfaceType.GetMethods())
            {
                AddMethodInfoIfValid(interfaceMethodInfos, method);
            }

            foreach (var methodinfo in interfaceMethodInfos)
            {
                int paramcount = methodinfo.GetParameters().Length;
                object[] args = new object[paramcount];
                Action<Interface> lambdacall = (i) => methodinfo.Invoke(i, args); 
                var calls = rhinomock.GetArgumentsForCallsMadeOn(lambdacall);
                foreach (var call in calls)
                {
                    bool more = false;
                    callbuilder.Clear().Append(interfaceType.Name).Append('.').Append(methodinfo.Name).Append('(');
                    foreach (var parameter in call)
                    {
                        if (more) { callbuilder.Append(", "); }
                        if (null == parameter) { callbuilder.Append("<null>"); }
                        else {
                            callbuilder
                                .Append('(').Append(parameter.GetType().Name).Append(")'")
                                .Append(parameter.ToString()).Append("'");
                        }
                        more = true;
                    }
                    callbuilder.Append(')');
                    string callInfo = callbuilder.ToString();
                    returnInfos.Add(callInfo);
                }
            }
            return returnInfos;
        }

        private static void AddMethodInfoIfValid(List<MethodInfo> interfaceMethodInfos, MethodInfo methodinfo)
        {
            if (null != methodinfo)
            {
                interfaceMethodInfos.Add(methodinfo);
            }
        }
    }
}
使用NUnit.Framework;
使用犀牛;
使用制度;
使用System.Collections.Generic;
运用系统反思;
使用系统文本;
名称空间StackOverflow\u名称空间
{
公共接口IUsefulService
{
对象HiddenAmongManyCalls();
字符串TestCall2(字符串arg1,int arg2);
字符串完全访问{get;set;}
字符串只读{get;}
}
公共类第三方数据库
{
私人INTA=42;
公共第三方基地(IUSEFULFSERVICE)
{
TestCall2(“callA”,1);
TestCall2(“callB”,1);
object liveFastDieYoung=service.hiddenamonyCalls();
TestCall2(“callA”,2);
TestCall2(“callB”,2);
var a=service.FULLACCESS;
var b=service.READONLY;
service.FULLACCESS=“some”;
liveFastDieYoung。等于(a);
}
}
公共类MyParty:第三方数据库
{
公共MyParty(IUsefulService服务):基本(服务)
{
}
}
[测试夹具]
类堆栈溢出
{
[测试]
公共空间
{
IUsefulService=MockRepository.GenerateMock();
尝试
{
var方=新的MyParty(服务);
}
捕获(例外e)
{
var calls=GetCallsList(服务);
foreach(var传入调用)
{
//使用visual studio testrunner for nunit 3,我可以调查存储的控制台输出
控制台写入线(呼叫);
}
Assert.Fail(“Excpexted无异常,但为“+e.GetType().Name+”:“+e.Message”);
}
}
私有IEnumerable GetCallsList(接口)
{
类型interfaceType=typeof(接口);
列表接口MethodInfo=新列表();
List returnInfos=新列表();
StringBuilder callbuilder=新建StringBuilder();
foreach(interfaceType.GetProperties()中的var属性)
{
AddMethodInfoIfValid(InterfaceMethodInfo,property.getMethod());
AddMethodInfoIfValid(InterfaceMethodInfo,property.GetSetMethod());
}
foreach(interfaceType.GetMethods()中的var方法)
{
AddMethodInfoIfValid(接口方法,方法);
}
foreach(InterfaceMethodInfo中的var methodinfo)
{
int paramcount=methodinfo.GetParameters().Length;
object[]args=新对象[paramcount];
Action lambdacall=(i)=>methodinfo.Invoke(i,args);
var calls=rhinomock.GetArgumentsForCallsMadeOn(lambdacall);
foreach(var传入调用)
{
布尔莫尔=假;
callbuilder.Clear().Append(interfaceType.Name).Append('.').Append(methodinfo.Name).Append('(');
foreach(调用中的var参数)
{
如果(更多){callbuilder.Append(“,”;}
if(null==参数){callbuilder.Append(“”;}
否则{
呼叫生成器
.Append(“(”).Append(parameter.GetType().Name).Append(“)”)
.Append(parameter.ToString()).Append(“”);
}
更多=正确;
}
callbuilder.Append(');
字符串callInfo=callbuilder.ToString();
returnInfos.Add(callInfo);
}
}
返回信息;
}
私有静态void AddMethodInfoIfValid(列表接口MethodInfo、MethodInfo MethodInfo)
{
if(null!=methodinfo)
{
接口方法添加(方法信息);
}
}
}
}

Yes rhinomock记录所有方法调用。您可以使用AssertWasCall来验证它们的执行情况。@OldFox我可以验证我所期望的一切,但是通过上面的调用,我希望创建一个报告来显示发生了什么。我不认为VerifyAllExpections能帮我做到这一点。在UTs中,你必须验证预期的行为。监视所有电话是一种不好的做法
verifyallexpections
无法解决您的问题。当您不想允许意外调用时,您必须使用严格的mock(今天使用这种mock被认为是一种不好的做法……)。如果您仍然希望访问记录:使用reflaction或下载rhinomock源代码并进行一些更改。。。。
using NUnit.Framework;
using Rhino.Mocks;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace StackOverflow_namespace
{
    public interface IUsefulService
    {
        object HiddenAmongManyCalls();
        string TestCall2(string arg1, int arg2);
        string FULLACCESS { get; set; }
        string READONLY { get; }
    }

    public class ThirdPartyBase
    {
        private int a = 42;

        public ThirdPartyBase(IUsefulService service)
        {
            service.TestCall2("callA", 1);
            service.TestCall2("callB", 1);
            object liveFastDieYoung = service.HiddenAmongManyCalls();
            service.TestCall2("callA", 2);
            service.TestCall2("callB", 2);
            var a = service.FULLACCESS;
            var b = service.READONLY;
            service.FULLACCESS = "some";
            liveFastDieYoung.Equals(a);
        }
    }

    public class MyParty : ThirdPartyBase
    {
        public MyParty(IUsefulService service) : base(service)
        {

        }
    }


    [TestFixture]
    class StackOverflow
    {
        [Test]
        public void Hypothetical()
        {
            IUsefulService service = MockRepository.GenerateMock<IUsefulService>();

            try
            {
                var party = new MyParty(service);
            }
            catch (Exception e)
            {
                var calls = GetCallsList(service);
                foreach (var call in calls)
                {
                    //with my visual studio testrunner for nunit 3 I can investigate stored console output
                    Console.WriteLine(call);
                }
                Assert.Fail("Excpexted no exception but was '" + e.GetType().Name + "': " + e.Message);
            }
        }

        private IEnumerable<string> GetCallsList<Interface>(Interface rhinomock)
        {
            Type interfaceType = typeof(Interface);
            List<MethodInfo> interfaceMethodInfos = new List<MethodInfo>();
            List<string> returnInfos = new List<string>();
            StringBuilder callbuilder = new StringBuilder();

            foreach (var property in interfaceType.GetProperties())
            {
                AddMethodInfoIfValid(interfaceMethodInfos, property.GetGetMethod());
                AddMethodInfoIfValid(interfaceMethodInfos, property.GetSetMethod());
            }
            foreach (var method in interfaceType.GetMethods())
            {
                AddMethodInfoIfValid(interfaceMethodInfos, method);
            }

            foreach (var methodinfo in interfaceMethodInfos)
            {
                int paramcount = methodinfo.GetParameters().Length;
                object[] args = new object[paramcount];
                Action<Interface> lambdacall = (i) => methodinfo.Invoke(i, args); 
                var calls = rhinomock.GetArgumentsForCallsMadeOn(lambdacall);
                foreach (var call in calls)
                {
                    bool more = false;
                    callbuilder.Clear().Append(interfaceType.Name).Append('.').Append(methodinfo.Name).Append('(');
                    foreach (var parameter in call)
                    {
                        if (more) { callbuilder.Append(", "); }
                        if (null == parameter) { callbuilder.Append("<null>"); }
                        else {
                            callbuilder
                                .Append('(').Append(parameter.GetType().Name).Append(")'")
                                .Append(parameter.ToString()).Append("'");
                        }
                        more = true;
                    }
                    callbuilder.Append(')');
                    string callInfo = callbuilder.ToString();
                    returnInfos.Add(callInfo);
                }
            }
            return returnInfos;
        }

        private static void AddMethodInfoIfValid(List<MethodInfo> interfaceMethodInfos, MethodInfo methodinfo)
        {
            if (null != methodinfo)
            {
                interfaceMethodInfos.Add(methodinfo);
            }
        }
    }
}