asp.net-mvc – 存储库模式和单元测试ASP.NET Web API
|
我刚刚开始深入研究单元测试,并且刚刚开始掌握存储库模式和IoC.但是,我不认为我完全理解它,因为它的一部分似乎有点傻.让我解释. 我的控制器: public class UserProfileController : ApiController
{
private IUserProfileRepository repository;
// Optional constructor,passes repository,allows dependency injection
public UserProfileController(IUserProfileRepository userProfileRepository)
{
this.repository = userProfileRepository;
}
// GET api/UserProfile
// Returns a list of all users
public IEnumerable<UserProfile> Get()
{
// Only Admins can see a list of users
if (Roles.IsUserInRole("Admin"))
{
return repository.Get();
}
else
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.Forbidden)
{
ReasonPhrase = "Administrator access required"
});
}
}
// Other methods,etc.
(请注意,我有一个依赖项,Roles.IsUserInRole(“Admin”),我无法弄清楚如何抽象,这会导致一些问题). 我典型的repo界面: public interface IUserProfileRepository : IDisposable
{
IEnumerable<UserProfile> Get();
// Other methods,etc.
}
回购: public class UserProfileRepository : IUserProfileRepository,IDisposable
{
private OfootContext context;
public UserProfileRepository(OfootContext context)
{
this.context = context;
}
public IEnumerable<UserProfile> Get()
{
return context.UserProfiles.AsEnumerable();
}
// ... More code
所以一切看起来都很好,我从业务逻辑中抽象出了业务访问层,现在我可以创建一个虚假的存储库来运行单元测试. 假回购: public class FakeUserProfileRepository : IUserProfileRepository,IDisposable
{
private List<UserProfile> context;
public FakeUserProfileRepository(List<UserProfile> context)
{
this.context = context;
}
public IEnumerable<UserProfile> Get()
{
return context.AsEnumerable();
}
和测试: [TestMethod]
public void GetUsers()
{
// Arrange
var items = new List<UserProfile>()
{
new UserProfile
{
UserId = 1,Username = "Bob",},new UserProfile
{
UserId = 2,Username = "Bob2",}
};
FakeUserProfileRepository repo = new FakeUserProfileRepository(
items);
UserProfileController controller = new UserProfileController(
repo);
// Act
IEnumerable<UserProfile> result = controller.Get();
// Assert
Assert.IsNotNull(result);
}
现在我们在同一页面上(并且随意指出任何’代码味道’),这是我的想法: >假存储库要求我重新实现我的所有Entity Framework逻辑并将其更改为处理List对象.这是我需要调试的链中的更多工作和更多链接. 如果我找到一种方法来抽象出用户帐号垃圾,我仍然只是在代码中乱码并创建更多代码(甚至可能是两倍多?因为我需要创建假货)我可以在其中替换Context. 我的问题是:我错过了什么?它是一个整体概念还是具体的东西? 解决方法你走在正确的轨道上.让事情正常运转总是令人痛苦,但你会发现它会在未来发展.我建议使用像Moq这样的框架,而不是创建“虚假”对象.它允许您设置测试时所需的行为,而不是重新实现整个接口.例如,在您的测试中,您可以简单地写: Mock<IUserProfileRepository> mockUserRepo = new Mock<IUserProfileRepository>();
var items = new List<UserProfile>()
{
new UserProfile
{
UserId = 1,}
};
mockUserRepo.Setup(m => m.Get().Returns(items.AsEnumerable());
UserProfileController controller = new UserProfileController(
mockUserRepo.Object);
// Act
IEnumerable<UserProfile> result = controller.Get();
//Now you can keep varying the mock response by changing the Setup(),so now
//check for null response handling,0 items,exceptions etc...
所有这些努力的最终结果是你完全将测试隔离到你的控制器,没有数据库依赖关系,你可以轻松改变输入而无需编写类,而是使用模拟设置. 如果您遵循这种简单的架构模式,您将获得令人敬畏的可测试性和明确的关注点分离.随着系统中的事情变得越来越复杂,您可以利用像Unity这样的DI容器. 在身份验证部分,我建议创建属性,您可以使用ASP.Net MVC使用:[Authorization(Roles =“Admin”)]作为示例来装饰您的方法.这创建了另一个有用的横切模式,使Auth资源与控制器中的业务逻辑分离. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – Internet Explorer的操作中止和延迟问题
- asp.net – 在没有Global.asax的情况下处理应用程序范围的事
- macos – ASP.NET CORE 2.1预览“Csc”任务不支持“SharedC
- asp.net:控件/页面的页面生命周期顺序与其中的用户contorl
- asp.net-mvc – 在活动的SignalR连接期间更改用户身份 – 如
- ASP.Net 分页控件源码
- 如何找到ASP.NET中的哪个对象无法序列化?
- asp.net-mvc-3 – 自定义成员资格提供程序和统一依赖注入
- asp.net-web-api2 – ASP.NET 5(vNext)/ Web API / OAuth /
- asp.net-mvc – 如何通过MVC Azure AD身份验证从AD获取角色
- asp.net-mvc – 如何将服务器错误的http状态代码
- asp.net-mvc – 我有15分钟向我的同事介绍ASP.NE
- asp.net-mvc-3 – 如何指定默认LayoutPage在Razo
- asp.net-mvc – ASP.NET MVC – 用于ICollection
- asp.net-mvc – 在asp.net mvc中的redirecttoact
- asp.net – .Net System.Mail.Message添加多个“
- asp.net-core – 从ActionFilterAttribute设置Vi
- asp.net-mvc – 我可以从HttpContext获取控制器吗
- asp.net-mvc – ASP.NET MVC – 如何获取一个动作
- asp.net-mvc – 将Ajax Jquery中的enum参数传递给
