相关疑难解决方法(0)

如何使用Moq模拟扩展方法?

我正在编写一个依赖于扩展方法结果的测试,但我不希望该扩展方法的未来失败会破坏此测试.模拟这个结果似乎是显而易见的选择,但是Moq似乎没有提供一种覆盖静态方法的方法(扩展方法的要求).与Moq.Protected和Moq.Stub有类似的想法,但它们似乎没有为这种情况提供任何东西.我错过了什么或者我应该以不同的方式去做这件事吗?

这是一个简单的例子,通常会对"不可覆盖的成员的无效期望"失败.这是需要模拟扩展方法的一个不好的例子,但它应该这样做.

public class SomeType {
    int Id { get; set; }
}

var ListMock = new Mock<List<SomeType>>();
ListMock.Expect(l => l.FirstOrDefault(st => st.Id == 5))
        .Returns(new SomeType { Id = 5 });
Run Code Online (Sandbox Code Playgroud)

至于任何可能建议我使用Isolator的TypeMock迷们:我很欣赏这项努力,因为看起来TypeMock可能会被蒙住眼睛和醉酒,但我们的预算不会很快增加.

c# extension-methods moq mocking

79
推荐指数
4
解决办法
6万
查看次数

MOQ - 如何模拟需要转换为另一个接口的接口?

我想要做的是为I1构建一个moq - 这很好......但是在我测试的方法过程中使用这个模拟我需要将它转换为I2才能访问一些不在的属性I1

Interface I1 
{ int AProperty{get;set;}}

Interface I2
{int AnotherProperty{get;set;}}
Run Code Online (Sandbox Code Playgroud)

然后我有一些对象

Class O1 : I1 {}
Run Code Online (Sandbox Code Playgroud)

Class O2 : O1 , I2 {}
Run Code Online (Sandbox Code Playgroud)

问题是,当我有一个I2实现对象的实例时,我可以将它转换为I1,以便访问通过该接口实现的方法.在代码中,这不是问题,并且每个标志都按预期工作.

在该类上编写单元测试时,唯一的问题就出现了.

接口还公开了一个名为GetNewInstance的方法,该方法返回一个初始化的实现对象实例,该实例对象被转换为IGetNewInstance接口...我通常可以模拟这个并使其自行返回(因此我继续使用模拟对象).

但是,当您尝试将此类型I2的返回对象转换为I1时,将引用空引用 - 这是有意义的,因为实现I2的模拟对象不会从继承I1的任何内容继承.

问题是我如何强制模拟对象同时从I1和I2继承?

inheritance unit-testing interface moq

66
推荐指数
1
解决办法
2万
查看次数

表达式引用不属于模拟对象的方法

我有一个api服务,调用另一个API服务.当我设置Mock对象时,它失败并出现错误:

NotSupportedException:expression引用不属于模拟对象的方法.

这是代码:

private Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>> _mockCarrierService;
private Mock<IApiService<AccountSearchModel>> _mockApiService;

[SetUp]
public void SetUp()
{
  _mockApiService = new Mock<IApiService<AccountSearchModel>>();
  _mockCarrierService = new Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>>();
  _mockApiService.Setup(x => x.GetFromApiWithQuery(It.IsAny<string>())).Returns(ApiValue());

  // Error occurred when call _mockApiService.GetFromApiWithQuery() in .Select()
  _mockCarrierService.Setup(x => x
            .Select(s => s
                .GetFromApiWithQuery(It.IsAny<string>())).ToList())
                .Returns(new List<IQueryable<AccountSearchModel>> { ApiValue() });
}
Run Code Online (Sandbox Code Playgroud)

用Moq阅读表达式测试,但它对我的情况不起作用.如果我删除它_mockCarrierService.Setup(),测试用例可以运行但是失败,NullReferenceException因为它没有有效的List<IQueryable<AccountSearchModel>>设置.

知道我怎么能做到这一点?


脚注:当前的解决方案

FWIW,这是我目前使用的解决方案.我很乐意更好地解决这个问题(直到Moq开始支持模拟扩展方法).

private List<ICarrierApiService<AccountSearchModel>> _mockCarrierService;
private AccountSearchController _mockController;
private Mock<ICarrierApiService<AccountSearchModel>> _mockApiService;

[SetUp]
public void SetUp()
{
   _mockApiService = …
Run Code Online (Sandbox Code Playgroud)

c# linq unit-testing expression moq

38
推荐指数
2
解决办法
2万
查看次数

你如何模拟 ILogger LogInformation

我有一个接收 ILogger 的类,我想模拟 LogInformation 调用,但这是一个扩展方法。我如何为此进行适当的设置调用?

c# logging mocking

27
推荐指数
6
解决办法
1万
查看次数

Moq IServiceProvider/IServiceScope

我正在尝试创建一个模拟(使用Moq),IServiceProvider以便我可以测试我的存储库类:

public class ApiResourceRepository : IApiResourceRepository
{
    private readonly IServiceProvider _serviceProvider;

    public ApiResourceRepository(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
        _dbSettings = dbSettings;
    }

    public async Task<ApiResource> Get(int id)
    {
        ApiResource result;

        using (var serviceScope = _serviceProvider.
            GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
            result = await
                context.ApiResources
                .Include(x => x.Scopes)
                .Include(x => x.UserClaims)
                .FirstOrDefaultAsync(x => x.Id == id);
        }

        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

我创建Mock对象的尝试如下:

Mock<IServiceProvider> serviceProvider = new Mock<IServiceProvider>();

serviceProvider.Setup(x => x.GetRequiredService<ConfigurationDbContext>())
    .Returns(new ConfigurationDbContext(Options, StoreOptions));

Mock<IServiceScope> serviceScope = new Mock<IServiceScope>(); …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing moq .net-core asp.net-core

18
推荐指数
5
解决办法
7558
查看次数

模拟IMemoryCache与Moq抛出异常

我正试图IMemoryCache用Moq 嘲笑.我收到这个错误:

Moq.dll中出现"System.NotSupportedException"类型的异常,但未在用户代码中处理

附加信息:表达式引用不属于模拟对象的方法:x => x.Get <String>(It.IsAny <String>())

我的嘲弄代码:

namespace Iag.Services.SupplierApiTests.Mocks
{
    public static class MockMemoryCacheService
    {
        public static IMemoryCache GetMemoryCache()
        {
            Mock<IMemoryCache> mockMemoryCache = new Mock<IMemoryCache>();
            mockMemoryCache.Setup(x => x.Get<string>(It.IsAny<string>())).Returns("");<---------- **ERROR**
            return mockMemoryCache.Object;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么我会收到这个错误?

这是测试中的代码:

var cachedResponse = _memoryCache.Get<String>(url);
Run Code Online (Sandbox Code Playgroud)

哪种_memoryCache类型IMemoryCache

我如何模拟_memoryCache.Get<String>(url)上面的内容并让它返回null?

编辑:我怎么做同样的事情,但为 _memoryCache.Set<String>(url, response);?我不介意它返回什么,我只需要将方法添加到mock中,这样它就不会在调用时抛出.

我试着回答这个问题的答案:

mockMemoryCache
    .Setup(m => m.CreateEntry(It.IsAny<object>())).Returns(null as ICacheEntry);
Run Code Online (Sandbox Code Playgroud)

因为在memoryCache扩展中它显示它CreateEntry在内部使用Set.但是"对象引用没有设置为对象的实例"是错误的.

c# unit-testing moq .net-core asp.net-core

16
推荐指数
3
解决办法
6388
查看次数

如何模拟(使用Moq)Unity方法

扩展方法不适合测试(这里描述:使用Moq模拟扩展方法,http://www.clariusconsulting.net/blogs/kzu/archive/2009/12/22/Howtomockextensionmethods.aspx).

但是可能有一些模拟Unity方法的解决方案?在我的情况下,我有以下功能:

public class MyManager
{
    public MyManager(IUnityContainer container) : base(container) { }

    public IResult DoJob(IData data)
    {
        IMyLog log = MyContainer.Resolve<IMyLog>();

        ... use log.Id ...

        MyContainer.Resolve<...>();//usage for other purposes...
    }
Run Code Online (Sandbox Code Playgroud)

我想确定'DoJob'方法总是从容器中获取'IMyLog'对象,但不是来自其他来源......我怎么能测试它?

我最初的想法是改变'DoJob'方法的实现和使用:

IMyLog log = UnityContainer.Resolve(typeof(IMyLog)) as IMyLog;
Run Code Online (Sandbox Code Playgroud)

但'Resolve(Type t,...)'也是一种扩展方法......

欢迎任何想法.

PS请注意,"我的日志"对象是远离MyManager.DoJob创建的...

.net extension-methods unit-testing moq mocking

13
推荐指数
3
解决办法
2万
查看次数

单元测试时 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
查看次数