我尝试为存储库类中的 Add 方法编写一个单元测试。我正在使用 EF6 和起订量。我的测试方法看起来:
public static Mock<DbSet<T>> CreateDbSetMock<T>(IEnumerable<T> elements) where T : class
{
var elementsAsQueryable = elements.AsQueryable();
var dbSetMock = new Mock<DbSet<T>>();
dbSetMock.As<IQueryable<T>>().Setup(m => m.Provider).Returns(elementsAsQueryable.Provider);
dbSetMock.As<IQueryable<T>>().Setup(m => m.Expression).Returns(elementsAsQueryable.Expression);
dbSetMock.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(elementsAsQueryable.ElementType);
dbSetMock.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(elementsAsQueryable.GetEnumerator());
return dbSetMock;
}
[Test()]
public void AddTest()
{
// Arrange
Mock<DbSet<Tytul>> titlesMock = CreateDbSetMock(new List<Tytul>());
Mock<OzinDbContext> titlesContextMock = new Mock<OzinDbContext>();
titlesContextMock.Setup(x => x.Tytuly).Returns(titlesMock.Object);
titlesMock.Setup(x => x.Add(It.IsAny<Tytul>())).Returns((Tytul t) => t);
IRepository<Tytul> tytulRepository = TytulRepository(titlesContextMock.Object);
Tytul tytul = new Tytul
{
Identyfikator = "ABC"
};
// …Run Code Online (Sandbox Code Playgroud) 我有一个包含数十种方法的类 - 我只需要使用其中两个方法并避免依赖注入。
Task<List<ApplicationUser>> GetAllContractors(CancellationToken cancellationToken);
Task<ApplicationUser> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken);
Run Code Online (Sandbox Code Playgroud)
我当前的尝试:(适用于所有承包商,因为我不需要任何参数即可生效)
users.AddRange(await ManifestJsonLoader.LoadAsync<List<ApplicationUser>>("Mynamespace.sampleUsers.json"));
var userProviderMock = new Mock<IUserProvider>(MockBehavior.Strict);
userProviderMock.Setup(service => service.GetAllContractors(CancellationToken.None)).Returns(Task.FromResult(users));
userProviderMock.Setup(service => service.FindByNameAsync(It.Is<string>(name => users.FirstOrDefault(d => d.UserName == name) != null), It.IsAny<CancellationToken>()));
Run Code Online (Sandbox Code Playgroud)
我一直在寻找“带有参数的最小起订量方法”,但到目前为止没有一个结果回答了我的问题。也许我在这里寻找错误的关键词。
我在一些集成测试中使用 Moq(更新不属于我自己的现有测试脚本和代码),并且我正在测试一个 BuinessService,其中注入了一个发送电子邮件的电子邮件接口。
public interface IEmailService
{
void CreateMailItem(string To, string Subject, string Body);
string GetEmailAddress(string staffmember);
}
Run Code Online (Sandbox Code Playgroud)
最初我只是 Moq'd IEmailService接口并且工作正常,但由于代码的实现方式,我需要调用默认接口实现(即EmailService)进行测试。我知道我不应该。
我知道我可以起订量如下所示的方法,但我想做的是让代码调用原始实现EmailService.CreateMailItem 并仅更改单个参数,以便将电子邮件发送到测试帐户而不是真实帐户。
var emailMock = new Mock<EmailService>() { CallBase = true };
emailMock.Setup(x => x.CreateMailItem("test@test.com", It.IsAny<string>(), It.IsAny<string>()));
email = emailMock.Object;
Run Code Online (Sandbox Code Playgroud)
我可以使用 Moq 调用原始 CreateMailItem 方法,但将“To”参数更改为我的测试电子邮件帐户并保留其他参数不变。
我正在尝试测试我拥有的一些代码:
public async Task<Sortation> SaveAsync(Sortation sortation)
{
if (sortation.Id == 0)
{
var sortations = await ListAsync(sortation.CategoryId);
sortation.Order = sortations.Count;
_sortationService.Create(sortation);
}
else
{
_sortationService.Update(sortation);
}
await _sortationService.SaveChangesAsync();
return sortation;
}
Run Code Online (Sandbox Code Playgroud)
ListAsync方法给我带来了一个问题。我这样设置我的测试:
[Test]
public async Task ShouldHaveOrderOfZero()
{
// Assemble
const string categoryId = "cameras";
var services = SortationContext.GivenServices();
var sortationProvider = services.WhenGetSortationProvider();
var sortations = new List<Sortation>();
var sortation = new Sortation { CategoryId = categoryId };
services.MockSortationService.Setup(x => x.List()).Returns(sortations.AsQueryable);
// Act
await sortationProvider.SaveAsync(sortation);
// Assert
sortation.Order.Should().Be(0); …Run Code Online (Sandbox Code Playgroud) GetString(IStringLocalizer, String, Object[])我有一个测试类,它在某个时候使用扩展方法本地化字符串
除了测试之外,以下内容将有效
public class ClassToTest
{
private readonly IStringLocalizer<SharedResource> _localizer;
public AnalyticsLogic(IStringLocalizer<SharedResource> localizer)
{
_localizer = localizer;
}
public async Task<string> SomeMethod()
{
return _localizer.GetString("key", DateTime.Today)); // "My Date: 31.10.2018" - will return null when testing
}
public async Task<string> SomeMethod2()
{
return _localizer.GetString("key"); // "My Date: {0:d}"
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我建立测试的方式:
public class ClassToTestTest
{
private readonly ClassToTest _testee;
private readonly Mock<IStringLocalizer<SharedResource>> _localizerMock = new Mock<IStringLocalizer<SharedResource>>();
public ClassToTestTest()
{
_testee = new ClassToTest(_localizerMock.Object);
_localizerMock.Setup(lm => lm["key"]).Returns(new LocalizedString("key", …Run Code Online (Sandbox Code Playgroud) 我需要模拟 Key Vault 的端点,以便知道我是否调用该函数来获取 Key Vault 一次。
我正在使用 C# 和 Moq(框架)开发它来进行测试。
界面如下:
public interface IKeyVaultConnection
{
string GetKeyVaultValue(string variableName);
}
Run Code Online (Sandbox Code Playgroud)
public class KeyVaultConnection
{
public KeyVaultClient keyVaultClient;
private string endpointKeyVault;
public KeyVaultConnection(string keyVaultAddress = "DefaultEndpoint")
{
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
endpointKeyVault = $"https://{ keyVaultAddress }.vault.azure.net";
}
private async Task<string> AsyncGetSecretValue(string keyName)
{
var secret = await keyVaultClient.GetSecretAsync($"{endpointKeyVault}/secrets/{ keyName }")
.ConfigureAwait(false);
return secret.Value;
}
public string GetKeyVaultValue(string variableName)
{
Task<string> task = Task.Run(async () => …Run Code Online (Sandbox Code Playgroud) 我正在使用 Nuget 包 Moq (v4.13.1)
我试图模拟的类/方法具有以下接口:
public interface IAgendaService
{
Task<IList<IMeeting>> GetRecentMeetingsMostRecentFirstAsync(
IWho who,
TimeSpan? timeSpan = null,
int? maxNumberOfMeetings = null);
}
Run Code Online (Sandbox Code Playgroud)
在我的测试方法中,我有以下代码来定义模拟:
Mock<IAgendaService> service = new Mock<IAgendaService>(MockBehavior.Strict);
service.SetupGet(x =>
x.GetRecentMeetingsMostRecentFirstAsync(
It.IsAny<IWho>(),
It.IsAny<TimeSpan?>(),
It.IsAny<int?>()))
.Returns(Task.FromResult((IList<IMeeting>)new List<IMeeting>()));
Run Code Online (Sandbox Code Playgroud)
当我运行测试时,service.SetupGet() 抛出以下异常:
测试方法 Agenda.Web.Tests.Controllers.HomeController.IndexTests.TestIndex 引发异常:System.ArgumentException:表达式不是属性访问:x => x.GetRecentMeetingsMostRecentFirstAsync(It.IsAny(), It.IsAny(), It。 IsAny()) 在 Moq.ExpressionExtensions.ToPropertyInfo(LambdaExpression 表达式) 在 Moq.Mock.SetupGet(Mock 模拟,LambdaExpression 表达式,Condition 条件) 在 Moq.Mock 1.SetupGet[TProperty](Expression1 表达式)
我究竟做错了什么?
DbContext我想知道当我使用 DI 向控制器提供数据库上下文时如何使用 Moq 来模拟我的 EF Core,如下所示:
public class RegisterController : Controller
{
private AppDbContext context;
public RegisterController(AppDbContext appDbContext)
{
context = appDbContext;
}
public IActionResult Create()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Create(Register register)
{
if (ModelState.IsValid)
{
context.Add(register);
await context.SaveChangesAsync();
return RedirectToAction("Read");
}
else
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
这AppDbContext是我的 EF 核心的数据库上下文。
我想为该操作编写测试用例Create。我尝试过以下代码:
[Fact]
public async Task Test_Create_POST_ValidModelState()
{
// Arrange
var r = new Register()
{
Id = 4,
Name = …Run Code Online (Sandbox Code Playgroud) 我有一个使用 执行请求的服务方法HttpClient。服务类构造函数IHttpClientFactory使用以下代码注入并创建客户端:
_httpClient = httpClientFactory.CreateClient(url);
Run Code Online (Sandbox Code Playgroud)
在我的测试构造函数中,我试图模拟PostAsync方法响应。
public MyServiceUnitTests()
{
_HttpClientMock = new Mock<IHttpClientFactory>();
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>("PostAsync", ItExpr.IsAny<string>(), ItExpr.IsAny<HttpContent>())
.ReturnsAsync(new HttpResponseMessage{ StatusCode = HttpStatusCode.OK });
var httpClient = new HttpClient(mockHttpMessageHandler.Object);
_HttpClientMock.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(httpClient);
_Service = new MyService(_HttpClientMock.Object);
}
Run Code Online (Sandbox Code Playgroud)
设置mockHttpMessageHandler 时出现以下错误:System.ArgumentException: 'No protected method HttpMessageHandler.PostAsync found whose signature is compatible with the provided arguments (string, HttpContent).'
我究竟做错了什么?
我的类/接口设置如下:
房间.cs
//import statements
namespace namespace1
{
internal class Room: Apartment
{
// constructor
public Room(Furniture furniture) : base(furniture)
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
公寓.cs
// import statements
namespace namespace2
{
public abstract class Apartment: Building
{
private int numChairs = 0;
// constructor
protected Apartment(IFurniture furniture) : base(IFurniture furniture)
{
this.numChairs = furniture.chairs.Length;
}
}
}
Run Code Online (Sandbox Code Playgroud)
建筑.cs
// import statements
namespace namespace3
{
public abstract class Building
{
// constructor
protected Building(IFurniture furniture)
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个 Room 对象,其中包含一个模拟的 …
c# ×10
moq ×10
unit-testing ×5
asp.net-core ×2
mocking ×2
nunit ×2
.net-core ×1
azure ×1
httpclient ×1
localization ×1