我不是 MVVM 模式的常客,这基本上是我第一次使用它。
我以前做的(“普通”WPF)是使用业务层和可能的数据层(通常包含由服务或实体框架创建的实体)创建我的视图。
现在经过一番玩弄后,我从 MVVM Light 创建了一个标准模板并执行了以下操作:
定位器:
public class ViewModelLocator
{
    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        if (ViewModelBase.IsInDesignModeStatic)
        {
            SimpleIoc.Default.Register<IUserService, DesignUserService>();
        }
        else
        {
            SimpleIoc.Default.Register<IUserService, IUserService>();
        }
        SimpleIoc.Default.Register<LoginViewModel>();
    }
    public LoginViewModel Login
    {
        get
        {
            return ServiceLocator.Current.GetInstance<LoginViewModel>();
        }
    }
}
登录视图模型:
public class LoginViewModel : ViewModelBase
{
    private readonly IUserService _userService;
    public RelayCommand<Object> LoginCommand
    {
        get
        {
            return new RelayCommand<Object>(Login);
        }
    }
    private string _userName;
    public String UserName
    {
        get { return _userName; }
        set
        {
            if (value == _userName)
                return;
            _userName = value;
            RaisePropertyChanged("UserName");
        }
    }
    /// <summary>
    /// Initializes a new instance of the LoginViewModel class.
    /// </summary>
    public LoginViewModel(IUserService userService)
    {
        _userService = userService;
        _closing = true;
    }
    private void Login(Object passwordBoxObject)
    {
        PasswordBox passwordBox = passwordBoxObject as PasswordBox;
        if (passwordBox == null)
            throw new Exception("PasswordBox is null");
        _userService.Login(UserName, passwordBox.SecurePassword, result =>
        {
            if (!result)
            {
                MessageBox.Show("Wrong username or password");
            }
        });
    }
}
绑定和命令工作正常,所以没有问题。设计和测试时间的商业模型类:
public class DesignUserService : IUserService
{
    private readonly User _testUser;
    private readonly IList<User> _users;
    public void Login(String userName, SecureString password, Action<Boolean> callback)
    {
        var user = _users.FirstOrDefault(u => u.UserName.ToLower() == userName.ToLower());
        if (user == null)
        {
            callback(false);
            return;
        }
        String rawPassword = Security.ComputeHashString(password, user.Salt);
        if (rawPassword != user.Password)
        {
            callback(false);
            return;
        }
        callback(true);
    }
    public DesignUserService()
    {
        _testUser = new User
        {
            UserName = "testuser",
            Password = "123123",
            Salt = "123123"
        };
        _users = new List<User>
        {
            _testUser
        };
    }
}
UserData 是一个调用数据库(实体框架)的静态类。
现在我有我的测试:
[TestClass]
public class Login
{
    [TestMethod]
    public void IncorrectUsernameCorrectPassword()
    {
        IUserService userService = new DesignUserService();
        PasswordBox passwordBox = new PasswordBox
        {
            Password = "password"
        };
        userService.Login("nonexistingusername", passwordBox.SecurePassword, b => Assert.AreEqual(b, false));
    }
}
现在我的测试不在 ViewModel 本身上,而是直接在业务层上。
基本上我有2个问题:
- 我是在正确的道路上,还是在我的模式实现中存在根本缺陷? 
- 如何测试我的 ViewModel?