我有一个方面排序列表。
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);
}
}
我有一个方法返回列表。
[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;
}
这是我的测试方法。
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();
}
}
因此,我想使用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();
}
}
}
接下来您可以将MockAspect
应用于您的目标班级:
[MockAspect]
public class SomeClass
{
[PostSharpExecuteAfterMethod]
public virtual List<string> GimmeSomeData()
{
throw new NotImplementedException();
}
}
这是您可以使用在方面之后调用的模拟的方法:
[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 ) );
}
}