我有一个 View ,我想模拟它的 Show
行为。
输入凭据后,[连接器]按钮将自行启用,然后用户可以单击。我希望我可以重现此行为,而无需显示 View 并实际输入我的凭据。
该应用程序是由 IApplicationPresenter
呈现的 WinForms MDI。 IApplicationPresenter
引发 IApplicationView
订阅的 ShowView
。
然后,当 IApplicationView.Shown
时,IApplicationPresenter
强制用户进行身份验证,如下所示:
IApplicationPresenter.OnViewShown
public void OnViewShown() { forceAuthentication(); }
private void forceAuthentication() {
IAuthenticationView authView = new AuthenticationView();
IAuthenticationPrenseter authPresenter = new AuthenticationPresenter();
authPresenter.ShowView();
}
就像我能闻到一种东西。
- 就像我可以将
IAuthenticationView
注入(inject)到IApplicationPresenter
中一样。然后,这将允许我将模拟 View 注入(inject)其中,并避免实际显示 View ,这实际上是我想要的。这是最好的制作方法吗?
现在,我想测试一下,当显示 IApplicationView
时,IApplicationPresenter
会收到通知并强制进行身份验证。
在 mock 方面有更好的方法吗?
UPDATE
IView
public interface IView {
void CloseView();
void SetTitle(string title);
void ShowView();
void RaiseVoidEvent(VoidEventHandler @event);
event VoidEventHandler OnViewInitialize;
event VoidEventHandler OnViewShown;
}
IApplicationView
public interface IApplicationView : IView {
void OnUserAuthenticated();
event VoidEventHandler ManageRequestsClicked;
}
IPresenter
public interface IPresenter<V> where V : IView {
V View { get; }
IDatabaseUser CurrentUser { get; }
void CloseView();
void OnViewInitialize();
void RaiseVoidEvent(VoidEventHandler @event);
void ShowView();
event VoidEventHandler OnCloseView;
event VoidEventHandler OnShowView;
}
演讲者
public abstract class Presenter<V> : IPresenter<V> where V : IView {
public Presenter(V view) {
if (view == null) throw new ArgumentNullException("view");
View = view;
View.OnViewInitialize += OnViewInitialize;
OnCloseView += View.CloseView;
OnShowView += View.ShowView;
}
public virtual IDatabaseUser CurrentUser { get; protected set; }
public virtual V View { get; private set; }
public virtual void CloseView() { RaiseVoidEvent(OnCloseView); }
public virtual void OnViewInitialize() { }
public void RaiseVoidEvent(VoidEventHandler @event) { if (@event != null) @event(); }
public virtual void ShowView() { RaiseVoidEvent(OnShowView); }
public virtual event VoidEventHandler OnCloseView;
public virtual event VoidEventHandler OnShowView;
}
IApplicationPresenter
public interface IApplicationPresenter : IPresenter<IApplicationView> {
IAuthenticationPresenter AuthenticationPresenter { get; set; }
void OnManageRequestsClicked();
void OnUserAuthenticated(UserAuthenticatedEventArgs e);
void OnViewShown();
}
ApplicationPresenter
public class ApplicationPresenter : Presenter<IApplicationView>, IApplicationPresenter {
public ApplicationPresenter(IApplicationView view) : this(view, null) { }
public ApplicationPresenter(IApplicationView view, IAuthenticationPresenter authPresenter) : base(view) {
AuthenticationPresenter = authPresenter;
View.OnViewShown += OnViewShown;
View.ManageRequestsClicked += OnManageRequestsClicked;
}
public IAuthenticationPresenter AuthenticationPresenter { get { return authenticationPresenter; } set { setAuthenticationPresenter(value); } }
public void OnManageRequestsClicked() {
var requests = new GestionDemandeAccesInformationForm();
requests.Database = database;
requests.MdiParent = (System.Windows.Forms.Form)View;
requests.Show();
}
public void OnUserAuthenticated(UserAuthenticatedEventArgs e) {
CurrentUser = new DatabaseUser(e.Login, e.Password, e.DatabaseInstance);
database = new DatabaseSessionFactory(CurrentUser);
setAppTitle();
showRequestsManagementView();
}
public void OnViewShown() { forceAuthentication(); }
}
IAuthenticationView
public interface IAuthenticationView : IView {
string ErrorMessage { get; set; }
string Instance { get; set; }
IEnumerable<string> Instances { get; set; }
string Login { get; set; }
string Password { get; set; }
void EnableConnectButton(bool enabled);
void SetDefaultInstance(string defaultInstance);
void RaiseSelectionChangedEvent(SelectionChangedEventHandler @event, SelectionChangedEventArgs e);
event VoidEventHandler OnConnect;
event SelectionChangedEventHandler OnDatabaseInstanceChanged;
event VoidEventHandler OnLoginChanged;
event VoidEventHandler OnPasswordChanged;
}
IAuthenticationPresenter
public interface IAuthenticationPresenter : IValidatablePresenter, IPresenter<IAuthenticationView> {
void OnConnect();
void OnViewDatabaseInstanceChanged(SelectionChangedEventArgs e);
void OnViewLoginChanged();
void OnViewPasswordChanged();
void RaiseUserAuthenticatedEvent(UserAuthenticatedEventArgs e);
event UserAuthenticatedEventHandler UserAuthenticated;
}
身份验证演示者
public class AuthenticationPresenter : Presenter<IAuthenticationView>, IAuthenticationPresenter {
public AuthenticationPresenter(IAuthenticationView view, IMembershipService service) : base(view) {
MembershipService = service;
View.ErrorMessage = null;
View.SetTitle(ViewTitle);
subscribeToEvents();
}
public bool IsValid { get { return credentialsEntered(); } }
public IMembershipService MembershipService { get; set; }
public virtual void OnConnect() {
if (noDatabaseInstanceSelected()) display(MissingInstanceErrorMessage);
else if (noLoginEntered()) display(MissingLoginErrorMessage);
else if (noPasswordEntered()) display(MissingPasswordErrorMessage);
else {
display(EverythingIsFine);
if (isAuthenticUser()) notifyTheApplicationThatTheUserIsAuthentic();
else { display(InvalidLoginOrPasswordErrorMessage); }
}
}
public override void OnViewInitialize() {
base.OnViewInitialize();
View.ErrorMessage = null;
View.Instances = Configuration.DatabaseInstances;
View.SetDefaultInstance(Configuration.DefaultInstance);
}
public void OnViewDatabaseInstanceChanged(SelectionChangedEventArgs e) { View.Instance = (string)e.Selected; }
public void OnViewLoginChanged() { View.EnableConnectButton(IsValid); }
public void OnViewPasswordChanged() { View.EnableConnectButton(IsValid); }
public void RaiseUserAuthenticatedEvent(UserAuthenticatedEventArgs e) { if (UserAuthenticated != null) UserAuthenticated(e); }
public event UserAuthenticatedEventHandler UserAuthenticated;
}
最佳答案
如果我是你,我会注入(inject)一个用于创建 AuthenticationPresenter
的工厂,并在你的测试中调用 OnViewShown()
并在你的模拟(演示者的)上进行验证由工厂返回)调用 ShowView
。
编辑 请注意,我还没有编译这个,我现在没有 C# 编译器。
这是我的测试版本。基于我对您真正想要测试的内容的解释:
[TestClass]
public class ApplicationPresenterTests
{
[TestClass]
public class OnViewShown : ApplicationPresenterTests
{
[TestMethod]
public void ForceAuthentication()
{
// given
var authenticationPresenterFactory = new Mock<IAuthenticationPresenterFactory>();
var authenticationPresenter = new Mock<IAuthenticationPresenter>();
authenticationPresenterFactory.Setup(f => f.create()).Returns(authenticationPresenter.Object);
var presenter = new ApplicationPresenter(authenticationPresenterFactory);
// when
presenter.OnViewShown();
// then
authenticationPresenter.Verify(p => p.ShowView());
}
}
关于c# - 如何最小起订量这个 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22669972/