我有一个方法,我想测试哪个期望IEnumerable<T>作为参数.
我目前正在嘲笑以下内容IEnumerable<T>(使用Moq):
var mockParent = new Mock<ICsvTreeGridExportable>();
var mockChild = new Mock<ICsvTreeGridExportable>();
Run Code Online (Sandbox Code Playgroud)
它如何将这些模拟对象放入其中,IEnumerable<T>以便我可以将它们作为参数传递给我想要测试的方法?
我正在测试的方法希望得到一个 IEnumerable<ICsvTreeGridExportable>
我正在使用EF 4.1来构建域模型.我有一个带有Validate(字符串userCode)方法的Task类,在其中我想确保用户代码映射到数据库中的有效用户,因此:
public static bool Validate(string userCode)
{
IDbSet<User> users = db.Set<User>();
var results = from u in users
where u.UserCode.Equals(userCode)
select u;
return results.FirstOrDefault() != null;
}
Run Code Online (Sandbox Code Playgroud)
我可以使用Moq来模拟IDbSet没问题.但是在Where调用时遇到了麻烦:
User user = new User { UserCode = "abc" };
IList<User> list = new List<User> { user };
var users = new Mock<IDbSet<User>>();
users.Setup(x => x.Where(It.IsAny<Expression<Func<User, bool>>>())).Returns(list.AsQueryable);
Initialization method JLTi.iRIS3.Tests.TaskTest.SetUp threw exception.
System.NotSupportedException: System.NotSupportedException: Expression
references a method that does not belong to the mocked object:
x => x.Where<User>(It.IsAny<Expression`1>()).
Run Code Online (Sandbox Code Playgroud)
除了创建一个间接级别(例如,使用ServiceLocator来获取运行LINQ的对象然后模拟该方法)之外,我想不出怎么测试这个,但我想确保以前没办法我介绍另一层.而且我可以看到经常需要这种LINQ查询,因此服务对象很快就会失控.
某种灵魂有帮助吗?谢谢!
我已经阅读了很多关于这个主题的其他QA,我仍然无法找到问题的解决方案,所以我决定公开我的案例.
我有这个界面
public interface IRepository<T> where T : class, IEntity
{
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
T FindIncluding(int id, params Expression<Func<T, object>>[] includeProperties);
}
Run Code Online (Sandbox Code Playgroud)
这是包含我想要设置的Mock的方法的基本结构
public PeopleController CreatePeopleController()
{
var mockUnitofWork = new Mock<IUnitOfWork>();
var mockPeopleRepository = new Mock<IRepository<Person>>();
mockPeopleRepository.Setup(r=>r.Find().Returns(new Person(){});
mockUnitofWork.Setup(p => p.People).Returns(mockPeopleRepository.Object);
return new PeopleController(mockUnitofWork.Object);
}
Run Code Online (Sandbox Code Playgroud)
我一直试图用这种方式设置模拟:
public PeopleController CreatePeopleController()
{
var mockUnitofWork = new Mock<IUnitOfWork>();
var mockPeopleRepository = new Mock<IRepository<Person>>();
mockPeopleRepository.Setup(r=>r.Find(It.isAny<Expression<Func<Person,bool>>>()).Single()).Returns(new Person(){});
mockUnitofWork.Setup(p => p.People).Returns(mockPeopleRepository.Object);
return new PeopleController(mockUnitofWork.Object);
}
Run Code Online (Sandbox Code Playgroud)
但系统总是抛出相同的异常"System.NotSupportedException:Expression引用一个不属于模拟对象的方法......"
另外我想补充说我正在使用MSTest和Moq
我知道使用Expression设置模拟并不容易,不推荐,但这对我来说非常重要因为"查找"是我在我的应用程序中大量使用的方法
使用MVC3.NET我在控制器中有一个文件上传方法,可以使用以下签名正常工作 public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> file)
如何使用NUnit对此进行单元测试?我环顾四周,每个人似乎都指向Moq,但我是单位测试新手,无法让Moq工作.
我找到了有趣的博客,例如:http://danielglyde.blogspot.com/2011/07/tdd-with-aspnet-mvc-3-moq-and.html但我很难弄清楚如何做同样的事情"伪造"文件上传,并且我也很谨慎,我现在设法找到的moq示例中的很多内容似乎已经弃用了代码.
我只想知道如何模拟HttpPostedFileBase,以便我可以使用Moq或其他方式测试我的上传代码 - 如果有人可以给我一些关于如何执行此操作的代码示例,我将非常感激.
以下代码取自其他示例:
var file = new Mock<HttpPostedFileBase>();
file.Setup(f => f.ContentLength).Returns(1);
file.Setup(f => f.FileName).Returns("test.txt");
controller.upload(file);
Run Code Online (Sandbox Code Playgroud)
我尝试编译时生成以下错误:
无法从'Moq.Mock'转换为'System.Web.HttpPostedFileBase'
我已经改变了方法,现在采用单个HttpPostedFileBase而不是IEnumerable,因为能够"模拟"一个是我试图关注的问题.
我正在设置一个Mock,如下所示.它被传递到目标的构造函数中.目标具有Decrypt方法,该方法在目标的生命周期内被调用两次.每次调用Decrypt方法时,都会在安装程序中处置"新建"的证书.但是,当第二次调用Decrypt对象时,我在尝试解密时获得了ObjectDisposed方法.如果我用调用GetCertificate()的ICertificateHelperAdapter的伪实现替换这个Mock,那么第二次调用Decrypt就可以正常工作.
我推断当我使用Mock时,它不会在后续调用GetCertificate时返回对象的新实例.这是设计的吗?
private Mock<ICertificateHelperAdapter> GetCertificateHelperAdapter()
{
Mock<ICertificateHelperAdapter> certificateHelper = new Mock<ICertificateHelperAdapter>();
certificateHelper.Setup(
ch => ch.GetCertificate(CertStoreName.My, StoreLocation.LocalMachine, It.IsAny<string>())).Returns(this.GetCertificate()).Verifiable();
return certificateHelper;
}
private X509Certificate2 GetCertificate()
{
return new X509Certificate2(Environment.CurrentDirectory + "\\" + "azureconfig.pfx", "dingos");
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Moq验证方法调用,但我无法正确地获得语法.目前我已将此作为我的验证:
repository.Verify(x => x.ExecuteNonQuery("fav_AddFavorites", new
{
fid = 123,
inputStr = "000456"
}), Times.Once());
Run Code Online (Sandbox Code Playgroud)
代码编译,但测试失败并出现错误:
Expected invocation on the mock once, but was 0 times:
x => x.ExecuteNonQuery("fav_AddFavorites", new <>f__AnonymousType0<Int32, String>(123, "000456"))
No setups configured.
Performed invocations:
IRepository.ExecuteNonQuery("fav_AddFavorites", { fid = 123, inputStr = 000456 })
Run Code Online (Sandbox Code Playgroud)
如何验证方法调用并匹配匿名类型的方法参数.
UPDATE
回答问题:
我试图验证方法被调用和参数是否正确.
我试图验证的方法的签名是:
int ExecuteNonQuery(string query, object param = null);
Run Code Online (Sandbox Code Playgroud)
设置代码很简单:
repository = new Mock<IRepository>();
Run Code Online (Sandbox Code Playgroud)
更新2
看起来这是Moq的一个问题,以及它如何处理.Net中的匿名类型.Paul Matovich发布的代码运行良好,但是,一旦代码和测试在不同的程序集中,测试就会失败.
我有一个单元测试我正在检查一个方法是否被调用一次,所以我尝试这样: -
这是我的ILicenseManagerService模拟,我通过construstor传递它的对象.
public Mock<ILicenseManagerService> LicenseManagerService { get { return SetLicenseManagerServiceMock(); } }
private Mock<ILicenseManagerService> SetLicenseManagerServiceMock()
{
var licencemangerservicemock = new Mock<ILicenseManagerService>();
licencemangerservicemock.Setup(m => m.LoadProductLicenses()).Returns(ListOfProductLicense).Verifiable();
return licencemangerservicemock;
}
public static async Task<IEnumerable<IProductLicense>> ListOfProductLicense()
{
var datetimeoffset = new DateTimeOffset(DateTime.Now);
var lst = new List<IProductLicense>
{
GetProductLicense(true, datetimeoffset, false, "1"),
GetProductLicense(true, datetimeoffset, false, "2"),
GetProductLicense(true, datetimeoffset, true, "3")
};
return lst;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用这个模拟对象来设置_licenseManagerService并在测试中的方法中调用LoadProductLicenses().像这样.许可证即将到期.
var licenses = (await _licenseManagerService.LoadProductLicenses()).ToList();
Run Code Online (Sandbox Code Playgroud)
我尝试验证对此方法的调用 -
LicenseManagerService.Verify(m => m.LoadProductLicenses(),Times.Once);
Run Code Online (Sandbox Code Playgroud)
但是,当我运行我的单元测试异常时,说方法根本没有被调用.我在哪里做错了?
编辑 @dacastro我在这里调用相同的模拟是我的单元测试.
[TestMethod]
[TestCategory("InApp-InAppStore")]
public async …Run Code Online (Sandbox Code Playgroud) 我想在使用moq框架的C#中为私有方法编写单元测试,我在StackOverFlow和Google中搜索,但是我找不到预期的结果.如果可以,请你帮助我.
我有一个方法
HostingEnvironment.QueueBackgroundWorkItem,我希望在这个调用之前对一些行为进行单元测试,但是,测试失败了System.InvalidOperationException : Operation is not valid due to the current state of the object.
我怀疑这需要模拟HostingEnvironment但不知道如何.
所以我有一个使用Moq的.Net RC1解决方案,我已经升级到RC2,我发现Moq.netcore是为了在新平台上运行而创建的.
我在我的NuGet.config中添加了aspnet-contrib
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="contrib" value="https://www.myget.org/F/aspnet-contrib/api/v3/index.json" />
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
Run Code Online (Sandbox Code Playgroud)
我已将moq.netcore添加到我的project.json文件中.
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0-rc2-*",
"type": "platform"
},
"dotnet-test-xunit": "1.0.0-rc2-173361-36",
"moq.netcore": "4.4.0-beta8",
"xunit": "2.1.0"
},
"testRunner": "xunit",
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net451+win8"
]
}
}
Run Code Online (Sandbox Code Playgroud)
基本上我遵循Cli测试抽象单元测试,并在实例化Mock对象时出现以下错误:
System.IO.FileNotFoundException :
Could not load file or assembly 'System.Diagnostics.TraceSource, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Stack Trace:
at Castle.DynamicProxy.Generators.MethodWithInvocationGenerator.BuildProxiedMethodBody(MethodEmitter emitter, …Run Code Online (Sandbox Code Playgroud) moq ×10
unit-testing ×5
.net ×3
c# ×3
tdd ×3
mocking ×2
.net-4.5.2 ×1
asp.net-core ×1
file ×1
linq ×1
moq-3 ×1
testing ×1
upload ×1
xunit ×1