首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >怎么才能拍到这幅画?

怎么才能拍到这幅画?
EN

Stack Overflow用户
提问于 2014-03-26 10:29:10
回答 2查看 936关注 0票数 2

我有一个观点,我想嘲笑Show的行为。

一旦输入了凭据,Connecter按钮就启用了自己,然后用户可以单击。我希望我能复制这种行为,而不必展示自己的观点,而且实际上是我的凭据。

该应用程序是由WinForms提供的IApplicationPresenter MDI。IApplicationPresenter引发IApplicationView订阅的ShowView

然后,当IApplicationView.Shown时,IApplicationPresenter强制用户进行如下身份验证:

IApplicationPresenter.OnViewShown

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void OnViewShown() { forceAuthentication(); }

private void forceAuthentication() {
    IAuthenticationView authView = new AuthenticationView();
    IAuthenticationPrenseter authPresenter = new AuthenticationPresenter();
    authPresenter.ShowView();
}

好像我能闻到一种味道。

  1. 就像我可以把IAuthenticationView注入IApplicationPresenter。然后,这将允许我将我的模拟视图注入到它,并避免视图实际显示,这实际上是我想要提出的。这是最好的办法吗?

现在,我想测试当显示IApplicationView时,通知IApplicationPresenter并强制进行身份验证。

有什么更好的方法来嘲笑这里吗?

更新

IView

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IView {
    void CloseView();
    void SetTitle(string title);
    void ShowView();
    void RaiseVoidEvent(VoidEventHandler @event);

    event VoidEventHandler OnViewInitialize;
    event VoidEventHandler OnViewShown;
}

IApplicationView

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IApplicationView : IView {
    void OnUserAuthenticated();

    event VoidEventHandler ManageRequestsClicked;
}

IPresenter

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
}

演示者

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IApplicationPresenter : IPresenter<IApplicationView> {
    IAuthenticationPresenter AuthenticationPresenter { get; set; }

    void OnManageRequestsClicked();
    void OnUserAuthenticated(UserAuthenticatedEventArgs e);
    void OnViewShown();
}

ApplicationPresenter

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IAuthenticationPresenter : IValidatablePresenter, IPresenter<IAuthenticationView> {
    void OnConnect();
    void OnViewDatabaseInstanceChanged(SelectionChangedEventArgs e);
    void OnViewLoginChanged();
    void OnViewPasswordChanged();
    void RaiseUserAuthenticatedEvent(UserAuthenticatedEventArgs e);
    event UserAuthenticatedEventHandler UserAuthenticated;
}

AuthenticationPresenter

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-26 11:23:30

如果我是您,我会为创建AuthenticationPresenter注入一个工厂,在您的测试中,我将调用OnViewShown()并在您的模拟(工厂返回的演示者)上验证ShowView是否被调用。

编辑注意到我还没有编译这个,我现在还没有C#编译器。

这是我的测试版本。根据我对你真正想要测试的东西的解释:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[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());
        }
}
票数 2
EN

Stack Overflow用户

发布于 2014-03-26 14:49:54

到目前为止,我已经想出了一个完美的解决方案。

这一切都是关于设置模拟对象,使其按预期工作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[TestClass]
public abstract class ApplicationPresenterTests {
    [TestClass]
    public class OnViewShown : ApplicationPresenterTests {
        [TestMethod]
        public void ForceAuthentication() {
            // arrange

            // act
            Presenter.OnViewShown();
            var actual = Presenter.CurrentUser;

            // assert
            Assert.IsNotNull(actual);
            Assert.IsInstanceOfType(actual, typeof(IDatabaseUser));
        }
    }

    [TestInitialize]
    public void ApplicationMainPresenterSetUp() {
        Mock<IAuthenticationView> authView = new Mock<IAuthenticationView>(MockBehavior.Strict);
        authView.SetupProperty(v => v.ErrorMessage);
        authView.SetupGet(v => v.Instance).Returns(RandomValues.RandomString());
        authView.SetupGet(v => v.Login).Returns(RandomValues.RandomString());
        authView.SetupGet(v => v.Password).Returns(RandomValues.RandomString());
        authView.Setup(v => v.CloseView());
        authView.Setup(v => v.SetTitle(It.IsAny<string>()));
        authView.Setup(v => v.ShowView()).Raises(v => v.OnConnect += null).Verifiable();

        Mock<IMembershipService> authService = new Mock<IMembershipService>(MockBehavior.Loose);
        authService.Setup(s => s.AuthenticateUser(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).Returns(true);

        IAuthenticationPresenter authPresenter = new AuthenticationPresenter(authView.Object, authService.Object);

        ApplicationView = new ApplicationForm();

        Presenter = new ApplicationPresenter(ApplicationView, authPresenter);
    }

    protected IApplicationView ApplicationView { get; private set; }
    protected IApplicationPresenter Presenter { get; private set; }
}

因此,关键的更改是将IAuthenticationPresenter的依赖性注入到IApplicationPresenter中,从而导致ApplicationPresenter构造器重载。

虽然这解决了我的问题,但我更好地理解了将PresenterFactory注入到ApplicationPresenter中的必要性,因为它是处理应用程序中所有内容的演示程序,也就是对每个有自己的演示程序的视图的调用。

在我面前还有一个更复杂的挑战要面对。敬请期待!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22669972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文