标签: moq

如何在 C# 中使用 Moq 测试 Add 方法

我尝试为存储库类中的 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)

c# nunit entity-framework moq

1
推荐指数
1
解决办法
5280
查看次数

Moq 可以模拟行为以便使用表达式方法参数吗?

我有一个包含数十种方法的类 - 我只需要使用其中两个方法并避免依赖注入。

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)

我一直在寻找“带有参数的最小起订量方法”,但到目前为止没有一个结果回答了我的问题。也许我在这里寻找错误的关键词。

c# moq

1
推荐指数
1
解决办法
1968
查看次数

Moq - 调用原始方法实现但更改输入参数之一

我在一些集成测试中使用 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”参数更改为我的测试电子邮件帐户并保留其他参数不变。

c# moq

1
推荐指数
1
解决办法
5243
查看次数

尝试模拟时,源 IQueryable 未实现 IDbAsyncEnumerable

我正在尝试测试我拥有的一些代码:

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)

c# nunit unit-testing entity-framework moq

1
推荐指数
1
解决办法
4854
查看次数

单元测试时 GetString(IStringLocalizer, String, Object[]) 返回 null

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)

c# unit-testing localization moq .net-core-2.1

1
推荐指数
1
解决办法
2521
查看次数

如何使用 Moq Azure Key Vault 进行单元测试

我需要模拟 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)

c# unit-testing moq azure azure-keyvault

1
推荐指数
1
解决办法
9934
查看次数

使用可选参数模拟异步方法会抛出表达式不是属性访问

我正在使用 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 表达式)

我究竟做错了什么?

c# unit-testing moq mocking

1
推荐指数
1
解决办法
832
查看次数

使用 Moq 和 xUnit 模拟 EF Core 数据库上下文?

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)

c# moq entity-framework-core .net-core asp.net-core

1
推荐指数
1
解决办法
6849
查看次数

Net Core使用HttpClient测试方法

我有一个使用 执行请求的服务方法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).'

我究竟做错了什么?

c# moq httpclient asp.net-core

1
推荐指数
1
解决办法
1678
查看次数

C#、Moq、单元测试:如何创建从另一个类继承的对象?

我的类/接口设置如下:

房间.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# unit-testing dependency-injection moq mocking

1
推荐指数
1
解决办法
60
查看次数