C# 如何在单元测试中调用Postsharp方面?

C# 如何在单元测试中调用Postsharp方面?,c#,unit-testing,postsharp,aspect,C#,Unit Testing,Postsharp,Aspect,我有一个方面排序列表 public override void OnInvoke(MethodInterceptionArgs args) { args.Proceed(); var string_list = (args.ReturnValue as List<string>); string_list.Sort(); Console.WriteLine("Postsharp Aspect içerisinde sıralanan koleksiy

我有一个方面排序列表

public override void OnInvoke(MethodInterceptionArgs args)
{
    args.Proceed();
    var string_list = (args.ReturnValue as List<string>);
    string_list.Sort();

    Console.WriteLine("Postsharp Aspect içerisinde sıralanan koleksiyon: ");
    foreach (var item in string_list)
    {
      Console.WriteLine(item);
    }
}
public覆盖void OnInvoke(MethodInterceptionArgs args)
{
args.procedure();
变量字符串_list=(args.ReturnValue作为列表);
string_list.Sort();
Console.WriteLine(“Postsharp Aspect içerisinde sıralanan koleksiyon:”);
foreach(字符串列表中的变量项)
{
控制台写入线(项目);
}
}
我有一个返回列表的方法

    [PostSharpExecuteAfterMethod]
    public virtual List<string> Liste_Döndür()
    {
        List<string> liste = new List<string>();
        liste.Add("g");
        liste.Add("b");
        liste.Add("hjh");
        liste.Add("a");

        Console.WriteLine("Method'dan dönen string liste: ");
        foreach (var item in liste)
        {
            Console.WriteLine(item);
        }

        return liste;
    }
[PostSharpExecuteAfterMethod]
公共虚拟列表列表
{
List liste=新列表();
列表。添加(“g”);
列表。添加(“b”);
列表添加(“hjh”);
列表。添加(“a”);
WriteLine(“方法”dan dönen string liste:”;
foreach(列表中的变量项)
{
控制台写入线(项目);
}
返回列表;
}
这是我的测试方法

  public class SomeClass
  {
    [PostSharpExecuteAfterMethod]
    public virtual List<string> GimmeSomeData()
    {
        throw new NotImplementedException();
    }
  }

[TestClass]
public class UnitTest1
{
    [TestMethod]
    //[PostSharpExecuteAfterMethod]
    public void TestMethod1()
    {
        var mock = new Mock<SomeClass>();
        mock.Setup(m => m.GimmeSomeData()).Returns(() => new List<string> { "1", "2", "3" });
        //liste
        var resultList = mock.Object.GimmeSomeData();
    }
}
公共类SomeClass
{
[PostSharpExecuteAfterMethod]
公共虚拟列表
{
抛出新的NotImplementedException();
}
}
[测试类]
公共类UnitTest1
{
[测试方法]
//[PostSharpExecuteAfterMethod]
公共void TestMethod1()
{
var mock=new mock();
Setup(m=>m.gimmemomedata())。返回(()=>newlist{“1”、“2”、“3”});
//李斯特
var resultList=mock.Object.GimmeSomeData();
}
}

所以,我想在使用Moq的测试方法中调用我的方面。每当我试图创建一个模拟类或其他东西时。它不起作用。我该怎么做

由于目标方法上拦截的顺序,代码示例中的方面没有被调用。模拟拦截器添加在PostSharp拦截器之前,因此它会在PostSharp方面有机会执行之前返回结果

在大多数情况下,这是理想的行为。您可以将方面视为方法中的附加代码。因此,您自己的代码和应用方面应该作为单个单元进行测试

如果您的用例要求您在测试期间分离方面和原始方法体,那么您需要确保在PostSharp方面之后调用模拟拦截器。您可以在下面找到一个示例
MockAspect
,它允许您实现这一点:

public interface IMockable<T> where T : class
{
    Mock<T> CreateMock();
}

[Conditional( "DEBUG" )] // Exclude mocking interceptor in release builds.
public class MockAspect : TypeLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
    {
        Type targetType = (Type) targetElement;
        yield return new AspectInstance( targetElement, (IAspect) Activator.CreateInstance( typeof( MockAspectImpl<> ).MakeGenericType( targetType ) ) );
    }
}

[PSerializable]
// Make sure we are ordered after our aspect PostSharpExecuteAfterMethod.
[AspectTypeDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, typeof( PostSharpExecuteAfterMethod ))]
public class MockAspectImpl<T> : IInstanceScopedAspect, IAdviceProvider, IMockable<T> where T : class
{
    [PNonSerialized]
    private Mock<T> mock;

    public object CreateInstance( AdviceArgs adviceArgs )
    {
        return new MockAspectImpl<T>();
    }

    public void RuntimeInitializeInstance()
    {
    }

    public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
    {
        yield return new IntroduceInterfaceAdviceInstance( typeof( IMockable<T> ) );
    }

    Mock<T> IMockable<T>.CreateMock()
    {
        this.mock = new Mock<T>();
        return this.mock;
    }

    [OnMethodInvokeAdvice]
    [MulticastPointcut( Targets = MulticastTargets.Method,
                        Attributes = MulticastAttributes.Instance | MulticastAttributes.Public | MulticastAttributes.Virtual )]
    public void OnMethodInvoke( MethodInterceptionArgs args )
    {
        if ( this.mock != null )
        {
            args.ReturnValue = args.Method.Invoke( mock.Object, args.Arguments.ToArray() );
        }
        else
        {
            args.Proceed();
        }
    }
}
这就是如何使用在方面之后调用的模拟:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var obj = new SomeClass();
        var mock = ( (IMockable<SomeClass>) obj ).CreateMock();
        mock.Setup( m => m.GimmeSomeData() ).Returns( () => new List<string> { "3", "1", "2" } );

        var resultList = obj.GimmeSomeData();

        Console.WriteLine( "Result: {0}", string.Join( ", ", resultList ) );
    }
}
[TestClass]
公共类UnitTest1
{
[测试方法]
公共void TestMethod1()
{
var obj=新的SomeClass();
var mock=((IMockable)obj.CreateMock();
Setup(m=>m.gimmemomedata())。返回(()=>newlist{“3”、“1”、“2”});
var resultList=obj.gimmemomedata();
WriteLine(“结果:{0}”,string.Join(“,”,resultList));
}
}
有夏普博士后页面。会有帮助吗?
[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var obj = new SomeClass();
        var mock = ( (IMockable<SomeClass>) obj ).CreateMock();
        mock.Setup( m => m.GimmeSomeData() ).Returns( () => new List<string> { "3", "1", "2" } );

        var resultList = obj.GimmeSomeData();

        Console.WriteLine( "Result: {0}", string.Join( ", ", resultList ) );
    }
}