调用原始Action的模拟对象
本文关键字:模拟 对象 Action 原始 调用 | 更新日期: 2023-09-27 18:21:12
我总是尽量避免使用服务定位器,但在这种情况下,我有从Base继承的模型,并引发我希望始终在UI线程上调度的事件(例如INotifyPropertyChanged)。我不能使用DI容器来保持模型构造函数为空。
在我的代码下面。
public abstract class Base
{
private static IMainThreadDispatcherService _dispatcherService;
/// <summary>
/// The main thread dispatcher.
/// </summary>
protected static IMainThreadDispatcherService DispatcherService
{
get
{
return _dispatcherService ??
(_dispatcherService = DependencyLocatorService.Resolve<IMainThreadDispatcherService>());
}
}
/// <summary>
/// Helper method to raise PropertyChanged events.
/// </summary>
/// <typeparam name="T">Type of the property.</typeparam>
/// <param name="selectorExpression">The expression to pass the property name.</param>
public virtual void OnPropertyChanged<T>(Expression<Func<T>> selectorExpression)
{
if (selectorExpression == null)
{
throw new ArgumentNullException("selectorExpression");
}
MemberExpression body = selectorExpression.Body as MemberExpression;
if (body == null)
{
throw new ArgumentException("The body must be a member expression");
}
DispatcherService.RequestMainThreadAction(() =>
{
NotifyPropertyChanged(selectorExpression);
});
}
}
/// <summary>
/// A service that holds on the UI thread dispatcher.
/// </summary>
public interface IMainThreadDispatcherService
{
/// <summary>
/// Invoke an action on main thread.
/// </summary>
/// <param name="action">The Action to invoke.</param>
/// <returns>True if successfully invoked.</returns>
bool RequestMainThreadAction(Action action);
}
/// <summary>
/// This class is an abstraction of the service locator.
/// </summary>
public class DependencyLocatorService : IDependencyLocatorService
{
/// <summary>
/// Constructs a new object instance injecting all required dependencies.
/// </summary>
/// <typeparam name="T">Type of.</typeparam>
/// <returns>The object instance constructed.</returns>
public T IocConstruct<T>()
{
// A resolver
}
/// <summary>
/// Resolves an instance of the specified type.
/// </summary>
/// <typeparam name="T">Type of.</typeparam>
/// <returns>The object instance.</returns>
public static T Resolve<T>() where T : class
{
try
{
// A resolver
}
catch(Exception)
{}
return null;
}
/// <summary>
/// Registers a singleton instance of type T.
/// </summary>
/// <typeparam name="T">The type to register.</typeparam>
/// <param name="instance">The instance.</param>
public static void RegisterSingleton<T>(T instance) where T : class
{
try
{
// A resolver
}
catch (Exception)
{
}
}
}
问题是,当我想对继承自Base
的模型进行单元测试时,事情开始变得困难起来。
我正在寻求更改体系结构以启用适当的单元测试并模拟方法DispatcherService.RequestMainThreadAction
,但仍然引发事件。我正在使用Moq框架,不确定是否可以以某种方式设置这种嘲讽,因为我希望调用原始Action。
您可以尝试在Moq设置中使用回调方法并调用其中的操作吗?
除非您确实需要Mock
,否则为什么不使用简单的存根呢?
public class DispatcherServiceStub : IMainThreadDispatcherService
{
public bool RequestMainThreadAction(Action action)
{
action();
}
}