我有一個在建構式中采用 AuthenticationStateProvider 的類。我想撰寫單元測驗并模擬它。
我希望能夠設定從呼叫 GetAuthenticationStateAsync 回傳的用戶。
const string userId = "123";
const string userName = "John Doe";
const string email = "[email protected]";
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, userId),
new Claim(ClaimTypes.Name, userName),
new Claim(ClaimTypes.Email, email),
};
var identity = new Mock<ClaimsIdentity>(claims);
var principal = new Mock<ClaimsPrincipal>(identity.Object);
var mockOfAuthenticationStateProvider = new Mock<AuthenticationStateProvider>();
var mockOfAuthState = new Mock<AuthenticationState>();
mockOfAuthenticationStateProvider.Setup(p =>
p.GetAuthenticationStateAsync()).Returns(Task.FromResult(mockOfAuthState.Object));
我收到此錯誤訊息:
Testfunction 拋出例外:System.ArgumentException:無法實體化類的代理:Microsoft.AspNetCore.Components.Authorization.AuthenticationState。找不到無引數建構式。(引數'constructorArguments')---> System.MissingMethodException:找不到型別'Castle.Proxies.AuthenticationStateProxy'的建構式。
uj5u.com熱心網友回復:
AuthenticationStateProvider是抽象的,所以如果你不能模擬它,你可以創建它的實作,如下所示:
public class FakeAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly ClaimsPrincipal _principal;
public FakeAuthenticationStateProvider(ClaimsPrincipal principal)
{
_principal = principal;
}
// This static method isn't really necessary. You could call the
// constructor directly. I just like how it makes it more clear
// what the fake is doing within the test.
public static FakeAuthenticationStateProvider ForPrincipal(ClaimsPrincipal principal)
{
return new FakeAuthenticationStateProvider(principal);
}
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
return Task.FromResult(new AuthenticationState(_principal));
}
}
你可以這樣設定:
const string userId = "123";
const string userName = "John Doe";
const string email = "[email protected]";
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, userId),
new Claim(ClaimTypes.Name, userName),
new Claim(ClaimTypes.Email, email),
};
// These don't need to be mocks. If they are the test likely
// won't behave correctly.
var identity = new ClaimsIdentity(claims);
var principal = new ClaimsPrincipal(identity);
var authenticationStateProvider =
FakeAuthenticationStateProvider.ForPrincipal(principal);
然后將其傳遞給任何其他依賴于AuthenticationStateProvider.
當我們創建一個假的實作而不是一個模擬時,它是可重用的,也更容易設定,所以它使測驗變得更小。
例如,如果您設定它的原因是為了讓 mock/fake 回傳具有某些宣告的用戶,那么您可以讓 fake 在其建構式中獲取一組宣告。然后建構式完成剩下的作業,使你的測驗更小。
例如,
public class FakeAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly ClaimsPrincipal _principal;
public FakeAuthenticationStateProvider(ClaimsPrincipal principal)
{
_principal = principal;
}
public static FakeAuthenticationStateProvider ForPrincipal(ClaimsPrincipal principal)
{
return new FakeAuthenticationStateProvider(principal);
}
public static FakeAuthenticationStateProvider ThatReturnsClaims(params Claim[] claims)
{
var identity = new ClaimsIdentity(claims);
var principal = new ClaimsPrincipal(identity);
return new FakeAuthenticationStateProvider(principal);
}
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
return Task.FromResult(new AuthenticationState(_principal));
}
}
現在您的測驗可以減少混亂:
var claims = new []
{
new Claim(ClaimTypes.NameIdentifier, "123"),
new Claim(ClaimTypes.Name, "John Doe"),
new Claim(ClaimTypes.Email, "[email protected]"),
};
var authenticationStateProvider = FakeAuthenticationStateProvider.ThatReturnsClaims(claims);
我通常在我的測驗專案中為他們創建一個名為“Fakes”的檔案夾。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/517086.html
上一篇:保存物體在資料庫中重復導航屬性
