我有一個單元測試來檢查我的AccountController.LogIn方法。返回重定向結果以指示成功,否則返回viewresult。單元測試自定義MembershipProvider.ValidateUser,使用Global.asax中的代碼
測試總是失敗,因爲返回類型始終是viewresult,即使測試應該返回成功,因爲憑據是有效的,但我無法確定問題出在哪裏。 我TestMethod的: CustomerRepositoryTest.cs
[TestMethod]
public void Can_Login_With_Valid_Credentials()
{
// Arrange
Mock<IAddressRepository> mockAddressRepository = new Mock<IAddressRepository>();
Mock<ICustomerRepository> mockCustomerRepository = new Mock<ICustomerRepository>();
Mock<IOrderRepository> mockOrderRepository = new Mock<IOrderRepository>();
LoginViewModel model = new LoginViewModel
{
Email = "[email protected]",
Password = "password"
};
AccountController target = new AccountController(mockCustomerRepository.Object, mockAddressRepository.Object, mockOrderRepository.Object);
// Act
ActionResult result = target.LogIn(model);
// Assert
Assert.IsInstanceOfType(result, typeof(RedirectResult));
Assert.AreEqual("", ((RedirectResult)result).Url);
}
當我運行測試,它在我的AccountController登錄方法失敗,當我打電話的ValidateUser AccountController.cs
if (Membership.ValidateUser(LoginModel.Email, LoginModel.Password))
{
...
return RedirectToRoute(new
{
controller = "Account",
action = "Details"
});
}
else
{
return View();
}
我定製的MembershipProvider ValidateUser看起來像這樣:
個AccountMembershipProvider.cs
public class AccountMembershipProvider : MembershipProvider
{
[Inject]
public ICustomerRepository repository { get; set; }
public override bool ValidateUser(string username, string password)
{
var cust = repository.GetAllCustomers().SingleOrDefault..
當我運行應用程序,通常即不是測試,登錄工作正常。在應用我注入CustomerRepository到自定義成員資格提供在的Global.asax:
public class MvcApplication : System.Web.HttpApplication
{
private IKernel _kernel = new StandardKernel(new MyNinjectModules());
internal class MyNinjectModules : NinjectModule
{
public override void Load()
{
Bind<ICustomerRepository>().To<CustomerRepository>();
}
}
protected void Application_Start()
{
_kernel.Inject(Membership.Provider);
...
難道在Global.asax代碼不同時,單元測試運行的情況下?所以我的自定義提供程序沒有被注入,因此失敗?
UPDATE 我嘲笑我的Provider類,並將模擬的CustomerRepository對象傳遞給它。
Mock<AccountMembershipProvider> provider = new Mock<AccountMembershipProvider>();
provider.Object.repository = mockCustomerRepository.Object;
然後我創建了一個針對設置方法我想測試:
mockCustomerRepository.Setup(m => m.IsValidLogin("[email protected]", "password")).Returns(true);
但不幸的是,我仍然得到一個失敗每次。爲了回答關於我是否需要一個真正的或模擬的對象進行測試的問題 - 我並不挑剔,我只是想讓它在這一刻起作用!
更新2
我做了這些變化,雖然它仍然失敗,這也讓我確定具體的問題。在調試測試,我發現,當我打電話覆蓋
Membership.ValidateUser(LoginModel.Email, LoginModel.Password)
的Membership.Provider是類型的SqlMembershipProvider的(這大概是默認的類型),因此驗證失敗。
如果我投的供應商到我的自定義提供...
((AccountMembershipProvider)Membership.Provider).ValidateUser(LoginModel.Email, LoginModel.Password)
我運行測試時得到一個InvalidCastException。所以看起來我的模擬AccountMembershipProvider沒有被用於測試,而是使用了默認的提供者。
我想你已經在註釋中指出這一點:
// set your mock provider in your AccountController
但是我不知道你的意思究竟是什麼 - 我沒有在我的AccountController一個屬性來指定供應商,並我沒有注入到構造函數中。
爲了讓您知道,我在一天的早些時候通過編輯添加了更多信息。不要猶豫,要求澄清或更具體的信息。 – Gilles 2012-02-02 00:24:12
@Gilles - 我實施了你的建議(見更新)。他們爲我澄清了很多,但每次都不幸失敗!我是否需要爲Provider和Repository類定義設置方法? – markpsmith 2012-02-02 11:27:56
我用一個例子更新我的帖子..基本上,如果你的提供者被嘲笑,沒有必要爲它的依賴創建模擬,因爲模擬對象不會調用它們。 – Gilles 2012-02-02 13:41:20