簡體   English   中英

嘲笑UserPrincipal

[英]Mocking UserPrincipal

我有一個類來處理密碼更改和交換郵箱的到期檢查。 我在UserPrincipal上檢查LastPasswordSet。

那TDD怎么樣?

我想通過編寫一些測試來檢查我的類是否正確處理了密碼檢查。 但我無法理解我如何模擬UserPrincipal.FindByIdentity(principalContext,[some username])。

如果密碼在過去90天內被更改,我即將編寫一個返回true / false的方法。 所以我想模擬UserPrincipal,這樣我就可以在我的測試中設置LastPasswordSet返回值,只是為了檢查我要編寫的“密碼需求更改通知”的邏輯。

我意識到這是一個老帖子,但最近我遇到了與原始海報相同的問題,在看完答案之后,我想我必須做同樣的事情。 我不希望別人讀這篇文章,像我一樣浪費寶貴的時間,所以我決定真正回答這篇文章。

在意識到沒有簡單的方法來包裝UserPrincipal功能,也不依賴於像建議的集成或端到端測試之后,我記得有一種模擬靜態類的方法。 話雖如此,下面是使用Telerik JustMock的確切方法

private void MockUserPrincipal()
    {
        //Mock principal context
        var context = Mock.Create<PrincipalContext>((action) => action.MockConstructor());

        //Mock user principal
        var user = Mock.Create(() => new UserPrincipal(context));           

        //Mock the properties you need
        Mock.Arrange(() => user.Enabled).Returns(true);
        Mock.Arrange(() => user.UserPrincipalName).Returns("TestUser");
        Mock.Arrange(() => user.LastPasswordSet).Returns(DateTime.Now);

        //Mock any functions you need
        Mock.Arrange(() => user.IsAccountLockedOut()).Returns(false);

        //Setup static UserPrincipal class
        Mock.SetupStatic<UserPrincipal>();

        //Mock the static function you need
        Mock.Arrange(() => UserPrincipal.FindByIdentity(Arg.IsAny<PrincipalContext>(), Arg.AnyString)).Returns(user);  

        //Now calling UserPrincipal.FindByIdentity with any context and identity will return the mocked UserPrincipal
    }

我會用精辟的短語回答這個問題

“不要嘲笑你不擁有的類型”

無法找到一個權威的博客來支持這一點。 示例鏈接 雖然它似乎歸功於Joe Walnes。

UserPrincipal如果我記得是一個與身份驗證相關的.Net框架類。 模擬不受您控制(可能更改)的類型可能導致脆弱的測試。

而是從UserPrincipal發現您的設計需要什么

  • 通過TDDing客戶端找到UserPrincipal間接實現或實現的角色
  • 在你的單元中模擬該角色測試並測試所有呼叫者。
  • 進行“集成測試”以確保您的實際實現在調用時在UserPrincipal上按下正確的按鈕。
  • 依靠端到端/驗收測試來查找所有組件串在一起時發生的錯誤。

老帖但有一個有效的例子。 即使你從不測試別人的代碼,你也想測試你的方法。 並且您的方法可能需要來自另一個方法返回的UserPrincipal數據。 現在說你需要檢查LastPasswordSet屬性。

  1. 右鍵單擊單元測試項目中的.dll System.DirectoryServices.AccountManagement 選擇“添加假裝配”。
  2. 添加此單元測試

     [TestMethod] public async Task ActiveDirectoryUserFactory_CreateUserAsyncAndWhatYouExpect() { // Arrange using(ShimsContext.Create()) { var userPrincipal = new System.DirectoryServices.AccountManagement.Fakes.ShimUserPrincipal(); var baseUserPrincipal = new System.DirectoryServices.AccountManagement.Fakes.ShimAuthenticablePrincipal(userPrincipal); baseUserPrincipal.LastPasswordSetGet = () => DateTime.Now; // Mock the returned UserPrincipal to use our userPrincipal, here's for Moq _class.Setup(x => x.GetUserAsync("param")) .Returns(Task.FromResult<UserPrincipal>(userPrincipal)); // Act, your method that gets your shimUserPrincipal from _class.GetUserAsync in your _target class (I understood you got the UserPrincipal from external source) var user = await _target.YourMethod(); // Assert Assert.IsNull(user); } } // method that does the code you want to test public async Task<Object> YourMethod() { var user = await _class.GetUserAsync("param"); var lastLogin = user.LastPasswordSet; return new Object() } 

Shims有很多資源,所以我讓它像這樣。 希望這可以幫助谷歌搜索“模擬UserPrincipal”的人。

我擔心UserPrincipal類不是TDD友好的。
如何將您需要的功能包裝在您的類中並進行模擬呢?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM