这里是控制器
var roles = Roles.GetAllRoles();
单元测试调用失败 并在
LogOnTest()(Error message is "The Role Manager feature has not been enabled.")
您能告诉我我的测试功能是否正确或需要更多逻辑/功能测试吗?
[TestMethod]
public void LogOnTest()
{
var target = new AccountController();
var membershipMock = MockRepository.GenerateMock<AccountMembershipService>();
var formsMock = MockRepository.GenerateMock<IFormsAuthenticationService>();
target.FormsService = formsMock;
target.MembershipService = membershipMock;
var model = new LogonModel() { USERNAME= "aa", Password = "aa"};
string returnUrl = null;
bool isLoginSuccess = true;
var actual = target.LogOnFromUser(model);
if (actual == null)
Assert.Fail("should have redirected");
}
控制器:
public ActionResult LogOn(LogonModel model)
{
if(MembershipService.ValidateUser(model.UsernName, model.Password))
{
FormsService.SignIn(model.UsernName, true);
var roles = Roles.GetAllRoles(); //Roles got failed here
return RedirectToAction("Index", "Event");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View("LogOn", model);
}
答案 0 :(得分:1)
您需要在静态Roles
类周围创建一个包装器,以便您可以注入一个您可以控制的模拟实现。基本上这可能类似于您的MembershipService
和FormsService
(可能称之为IRoleService
),并且需要使用方法GetAllRoles()
。
你可以在你的控制器的null arg构造函数中创建默认实现(它只会委托给当前的静态类)(这是我想象的会员和表单服务,并提供一个属性,允许你像其他人一样以超越的方式覆盖它。
另一个选择是扩展您的会员服务,以允许您调用此方法,而不是专门为角色创建另一个服务。这违反了单一责任原则,因此不一定是个好主意,但它确实意味着您不必注入另一个依赖关系,并且可以认为获得成员的角色属于会员服务的职权范围。
老实说,我认为你最好更改你的控件,以便有一个构造函数,它明确要求实现成员资格服务,表单服务和角色服务,并在测试中提供模拟。这使得它明确了控制器的依赖性。然后,您需要升级到创建控制器的新方法,因为默认情况下只有具有默认构造函数才能创建控制器。你在这里有几个选择。保留您拥有的选项并使用默认值,或实现您自己的ControllerFactory
。一些细节here。我个人更喜欢ControllerFactory
方法。
答案 1 :(得分:1)
理论上,我更喜欢@Sam的方法,但我仍在努力让它适应我的依赖注入。我真的希望能够模拟我自己的数据并完全控制我的测试。
但是,作为一个止损点,我在这里找到了一个建议:http://blog.gfader.com/2009/11/aspnet-how-to-show-all-roles-of-current.html
由此我将下面的代码添加到App.config中,我可以继续进行测试。
<system.web>
<roleManager enabled="true"
defaultProvider="AspNetWindowsTokenRoleProvider" />
</system.web>