目前我有:
[Test]
public void DrawDrawsAllScreensInTheReverseOrderOfTheStack() {
// Arrange.
var screenMockOne = new Mock<IScreen>();
var screenMockTwo = new Mock<IScreen>();
var screens = new List<IScreen>();
screens.Add(screenMockOne.Object);
screens.Add(screenMockTwo.Object);
var stackOfScreensMock = new Mock<IScreenStack>();
stackOfScreensMock.Setup(s => s.ToArray()).Returns(screens.ToArray());
var screenManager = new ScreenManager(stackOfScreensMock.Object);
// Act.
screenManager.Draw(new Mock<GameTime>().Object);
// Assert.
screenMockOne.Verify(smo => smo.Draw(It.IsAny<GameTime>()), Times.Once(),
"Draw was not called on screen mock one");
screenMockTwo.Verify(smo => smo.Draw(It.IsAny<GameTime>()), Times.Once(),
"Draw was not called on screen mock two");
}
Run Code Online (Sandbox Code Playgroud)
但是我在生产代码中绘制对象的顺序并不重要.我可以先做一个,或者两个没关系.然而,它应该重要,因为绘制顺序很重要.
你如何(使用Moq)确保按特定顺序调用方法?
编辑
我摆脱了那个考验.draw方法已从我的单元测试中删除.我只需要手动测试它的工作原理.尽管顺序的逆转被带入了一个单独的测试类,在那里测试它并不是一件坏事.
感谢您关注的功能链接.我当然希望它能很快得到补充,非常方便.
我们正在使用Moq对我们的服务类进行单元测试,但是他们仍然坚持如何测试服务方法调用同一类的另一个服务方法的情况.我尝试将被调用的方法设置为虚拟,但仍然无法弄清楚在Moq中要做什么.例如:
public class RenewalService : IRenewalService
{
//we've already tested this
public virtual DateTime? GetNextRenewalDate(Guid clientId)
{
DateTime? nextRenewalDate = null;
//...<snip> a ton of already tested stuff...
return nextRenewalDate;
}
//but want to test this without needing to mock all
//the methods called in the GetNextRenewalDate method
public bool IsLastRenewalOfYear(Renewal renewal)
{
DateTime? nextRenewalDate = GetNextRenewalDate(renewal.Client.Id);
if (nextRenewalDate == null)
throw new Exceptions.DataIntegrityException("No scheduled renewal date, cannot determine if last renewal of year");
if (nextRenewalDate.Value.Year != renewal.RenewDate.Year)
return true; …Run Code Online (Sandbox Code Playgroud) 为了填写一些细节,我目前正在尝试更新AutofacContrib.Moq以使用最新的Moq.对于.NET-3.5及以下版本,我没有遇到任何问题.但在.NET-4中,安全限制会导致许多安全异常.
Moq有一个单一的方法,GetObjectData用SecurityCritical属性标记.AutofacContrib.Moq具有AllowPartiallyTrustedCallers属性集,该属性是异常的来源.似乎不是添加SecurityRulesSecurityLevel为1 的属性,而是最好删除AllowPartiallyTrustedCallers属性.我相信这默认会使程序集SecurityTransparent,这可能是不够的(尽管AutofacContrib.Moq单元测试通过).
我目前的主要问题是,针对.NET-4的程序集是否应该使用AllowPartiallyTrustedCallers属性?但是,鉴于我绝对不了解所有内容,在使用安全标记的程序集时应该考虑哪些细节?我是否需要在其使用的那些地方,直接或间接地使用安全属性明确标记我的程序集SecurityCritical?
使用Moq,我希望能够验证传递给模拟方法调用的参数是否满足某些条件.在这种情况下,我想检查传递给mocked方法的列表是否具有一定的大小:
var mockSomeRepository = new Mock<SomeRepository>();
mockSomeRepository.Setup(m => m.Write(It.IsAny<List<SomeDTO>>())).Verifiable();
var mainClass = new MainClass(mockSomeRepository.Object);
List<SomeDTO> someList = GetListWith25Items();
mainClass.DoRepositoryWrite(someList); // calls SomeRepository.Write(someList);
mockSomeRepository.Verify(m =>
m.Write(It.Is<List<SomeDTO>>(l => l.Count() == 25)), Times.Once());
Run Code Online (Sandbox Code Playgroud)
验证断言抛出一个异常,表示永远不会以这种方式调用该方法.但是,删除约束并使用Is.Any<List<SomeDTO>>()相反会导致传递.我不确定我是否在这里使用It.Is <>() - 这是我直觉地希望我的测试看起来像但我不确定我是否正确使用框架.我应该如何正确地构建这个测试?
以下使用EF 4.2的测试现在抛出EF 4.3的下一个异常
System.ArgumentException:类型为mock必须是接口或抽象或非密封类.----> System.TypeLoadException:来自程序集'DynamicProxyGenAssembly2,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null'的类型'Castle.Proxies.DbContext43Proxy'上的方法'CallValidateEntity'正在覆盖从中看不到的方法那个集会.
[Test]
public void CanCreateMoqTest()
{
// Arrange
Mock<DbContext43> mock;
// Act
mock = new Mock<DbContext43>();
// Assert
Assert.NotNull(mock.Object);
}
public class DbContext43:DbContext
{
}
Run Code Online (Sandbox Code Playgroud)
我该怎么办?为我的DbContext43创建一个界面?
这是4.2和4.3之间的突破性变化吗?
谢谢!!
我使用Moq来创建数据集的模拟.
我创建了一个小助手类,它允许我有一个内存存储而不是数据库,使单元测试变得轻而易举.这样我可以添加和删除我的模拟数据集中的项目,这允许我测试我的插入和删除服务调用.
在模拟的设置过程中,我有一行如下所示
this.Setup(i => i.AcademicCycles).Returns(mockStore.GetList<AcademicCycle>());
Run Code Online (Sandbox Code Playgroud)
我的模拟有很多属性,所以我想使用反射执行此设置步骤.我已经设法Returns通过反射工作的过程的一部分,但我坚持lambda方法Setup.
Setup 需要一个
Expression<Func<GoalsModelUnitOfWork, IQueryable<AcademicCycle>>> 对应于 i => i.AcademicCycles
我想动态创建它.使用反射我有以下内容:
物业名称:"AcademicCycles"
类型 IQueryable<AcademicCycle>
类型 AcademicCycle
我也有ilambda语句中的实例,它是一个GoalsModelUnitOfWork
我正在尝试从Microsoft Sync Framework模拟一个类.它只有一个内部构造函数.当我尝试以下内容时:
var fullEnumerationContextMock = new Mock<FullEnumerationContext>();
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
System.NotSupportedException:Parent没有默认构造函数.必须显式定义默认构造函数.
这是堆栈跟踪:
System.Reflection.Emit.TypeBuilder.DefineDefaultConstructorNoLock(MethodAttributes attributes)System.Reflection.Emit.TypeBuilder.DefineDefaultConstructor(MethodAttributes attributes)System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()System.Reflection.Emit.TypeBuilder.CreateType()Castle. DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type [] interfaces,ProxyGenerationOptions options)Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxy(Type classToProxy,Type [] additionalInterfacesToProxy,ProxyGenerationOptions options)Castle. DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy,Type [] additionalInterfacesToProxy,ProxyGenerationOptions options)Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy,Type [] additionalInterfacesToProxy,ProxyGenerationOptions options,Object [] constructorArguments,IInterceptor [] interceptors)Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy,Type [] additionalInterfacesToProxy,ProxyGenerationOptions options,IInterceptor [] interceptors)Castle.DynamicProxy .ProxyGenerator.CreateClassProxy(类型classToProxy,Type [] additionalInterfacesToProxy,IInterceptor []拦截器)Moq.MockDynamicProxy.ProxyGenerator.CreateClassProxy(类型classToProxy,Type [] additionalInterfacesToProxy,IInterceptor []拦截器)Moq.MockDynamicProxy.ProxyGenerator.CreateClassProxy(类型classToProxy,Type [] additionalInterfacesToProxy,IInterceptor []拦截器)Moq.Mock
1.<InitializeInstance>b__0() Moq.PexProtector.Invoke(Action action) Moq.Mock1.InitializeInstance()
我该如何解决这个问题呢?
我需要以HttpResponseBase.ApplyAppPathModifier这样的方式进行模拟,即ApplyAppPathModifier模拟自动返回调用参数.
我有以下代码:
var httpResponseBase = new Mock<HttpResponseBase>();
httpResponseBase.Setup(hrb => hrb.ApplyAppPathModifier(/*capture this param*/))
.Returns(/*return it here*/);
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
编辑:
在Moq文档的第一页(http://code.google.com/p/moq/wiki/QuickStart)上找到了解决方案:
var httpResponseBase = new Mock<HttpResponseBase>();
httpResponseBase.Setup(hrb => hrb.ApplyAppPathModifier(It.IsAny<string>)
.Returns((string value) => value);
Run Code Online (Sandbox Code Playgroud)
我突然觉得很愚蠢,但我想这就是你在23:30写代码时会发生什么
我正在使用Moq并且想要创建构建器类来创建具有预设合理默认值的模拟,可以根据需要在测试设置期间覆盖这些默认值.我采用的方法使用扩展方法,我传递输入参数值和预期输出.在这样做的过程中,我看到了在我看来是语义上等效的代码中的不同行为:在一个设置中直接传递It.IsAny()与在设置中间接传递It.IsAny()的值.例:
public interface IFoo
{
bool Bar(int value);
bool Bar2(int value);
}
public class Foo : IFoo
{
public bool Bar(int value) { return false; }
public bool Bar2(int value) { return false; }
}
var mock = new Mock<IFoo>();
mock.Setup(x => x.Bar(It.IsAny<int>())).Returns(true);
Assert.IsTrue(mock.Object.Bar(123)); // Succeeds
var myValue = It.IsAny<int>();
mock.Setup(x => x.Bar2(myValue)).Returns(true);
Assert.IsTrue(mock.Object.Bar2(123)); // Fails
Run Code Online (Sandbox Code Playgroud)
两个调用都是等价的(对我来说),但对Bar2的调用无法断言.为什么是这样?
我目前正在尝试对通过实体框架运行的查询运行一些单元测试.查询本身在实时版本上运行没有任何问题,但单元测试总是失败.
我把它缩小到我对DbFunctions.TruncateTime的使用,但我不知道如何通过这种方式来获得单元测试以反映实时服务器上发生的情况.
这是我正在使用的方法:
public System.Data.DataTable GetLinkedUsers(int parentUserId)
{
var today = DateTime.Now.Date;
var query = from up in DB.par_UserPlacement
where up.MentorId == mentorUserId
&& DbFunctions.TruncateTime(today) >= DbFunctions.TruncateTime(up.StartDate)
&& DbFunctions.TruncateTime(today) <= DbFunctions.TruncateTime(up.EndDate)
select new
{
up.UserPlacementId,
up.Users.UserId,
up.Users.FirstName,
up.Users.LastName,
up.Placements.PlacementId,
up.Placements.PlacementName,
up.StartDate,
up.EndDate,
};
query = query.OrderBy(up => up.EndDate);
return this.RunQueryToDataTable(query);
}
Run Code Online (Sandbox Code Playgroud)
如果我注释掉带有DbFunctions的行,则测试全部通过(除了检查只运行给定日期的有效结果的那些).
有没有办法可以提供在这些测试中使用的DbFunctions.TruncateTime的模拟版本?本质上它应该只返回Datetime.Date,但在EF查询中不可用.
编辑:这是使用日期检查失败的测试:
[TestMethod]
public void CanOnlyGetCurrentLinkedUsers()
{
var up = new List<par_UserPlacement>
{
this.UserPlacementFactory(1, 2, 1), // Create a user placement that is current
this.UserPlacementFactory(1, 3, 2, …Run Code Online (Sandbox Code Playgroud) c# ×10
moq ×10
unit-testing ×4
testing ×2
.net-4.0 ×1
autofac ×1
expression ×1
lambda ×1
mocking ×1
reflection ×1
security ×1