public static class ApplicationUtils
{
public static bool IsCurrentUserAManager()
{
var username = WindowsIdentity.GetCurrent().Name;
bool inAdmin;
if (username == "AdminUser") {
inAdmin = true;
} else {
inAdmin = false;
}
return inAdmin;
}
}
Run Code Online (Sandbox Code Playgroud)
以上是一些用于测试当前登录用户是否为管理员的代码,我想通过传入不同的用户名来对本节进行单元测试,并测试结果是否正确。
我听说依赖注入是最好的方法。但我不知道如何依赖注入静态类和静态方法。
任何人都可以帮助我填写下面的 TestMethod 以传递用户名并测试该方法吗?(不使用企业)
[TestMethod]
public void IsCurrentUserAManagerTestIsAdmin()
{
}
Run Code Online (Sandbox Code Playgroud)
稍微重构你的类以将身份作为参数。
public static class ApplicationUtils
{
public static bool IsUserAManager(IIdentity identity)
{
if (identity == null)
throw new NullReferenceException("identity");
return identity.Name == "AdminUser";
}
}
Run Code Online (Sandbox Code Playgroud)
和你的测试类使用最小起订量
[TestMethod]
public void IsUserAManagerTestIsAdminReturnsFalse()
{
var mockedIdentity = new Moq.Mock<IIdentity>();
mockedIdentity.Setup(x => x.Name).Returns("notanadmin");
var result = ApplicationUtils.IsUserAManager(mockedIdentity.Object);
Assert.IsFalse(result);
}
[TestMethod]
public void IsUserAManagerTestIsAdminReturnsTrue()
{
var mockedIdentity = new Moq.Mock<IIdentity>();
mockedIdentity.Setup(x => x.Name).Returns("AdminUser");
var result = ApplicationUtils.IsUserAManager(mockedIdentity.Object);
Assert.IsTrue(result);
}
Run Code Online (Sandbox Code Playgroud)
人们应该尽量避免将代码耦合到静态类,因为它们很难测试。
也就是说,按照您当前的代码,可以对其进行重构,以允许某些关注点分离,并通过扩展方法提供更流畅的 API。
public static class ApplicationUtils {
public static Func<IIdentity> userFactory = () => WindowsIdentity.GetCurrent();
public static IIdentity CurrentUser { get { return userFactory(); } }
public static bool IsManager(this IIdentity identity) {
return identity != null && string.Compare(identity.Name, "AdminUser", true) == 0;
}
public static bool IsAuthenticated(this IIdentity identity) {
return identity != null && identity.IsAuthenticated;
}
}
Run Code Online (Sandbox Code Playgroud)
下面以测试为例,演示一下上面的使用方法。
Moq 被用作模拟框架
[TestMethod]
public void IsManager_Should_Return_True_For_AdminUser() {
//Arrange
var name = "AdminUser";
var identity = Mock.Of<IIdentity>(_ => _.Name == name);
ApplicationUtils.userFactory = () => identity;
//Act
var actual = ApplicationUtils.CurrentUser.IsManager();
//Assert
Assert.IsTrue(actual);
}
Run Code Online (Sandbox Code Playgroud)
完成后,我现在建议您重构代码以使其更加可靠。
将当前用户转移到服务提供商的功能进行抽象。
public interface IIdentityProvider {
IIdentity CurrentUser { get; }
}
Run Code Online (Sandbox Code Playgroud)
非常简单,实现更简单。
public class DefaultIdentityProvider : IIdentityProvider {
public IIdentity CurrentUser {
get { return WindowsIdentity.GetCurrent(); }
}
}
Run Code Online (Sandbox Code Playgroud)
如果使用 DI,您现在可以将提供程序注入到需要访问当前用户的依赖类中。
这使得代码更加灵活和可维护,因为提供者和用户的模拟/存根可用于隔离的单元测试。扩展方法保持不变,因为它们的关注点非常简单。
下面是对之前的扩展方法进行测试的简单示例。
[TestMethod]
public void IsManager_Should_Return_True_For_AdminUser() {
//Arrange
var name = "AdminUser";
var identity = Mock.Of<IIdentity>(_ => _.Name == name);
var provider = Mock.Of<IIdentityProvider>(_ => _.CurrentUser == identity);
//Act
var actual = provider.CurrentUser.IsManager();
//Assert
Assert.IsTrue(actual);
}
Run Code Online (Sandbox Code Playgroud)
纯粹出于演示目的,扩展方法的测试IsManager实际上只需要IIdentity进行。
Assert.IsTrue(Mock.Of<IIdentity>(_ => _.Name == "AdminUser").IsManager());
Run Code Online (Sandbox Code Playgroud)