我正在为我创建的记录器类编写一些单元测试,我想模拟文件类.我找不到我需要用来创建MOQ的接口...那么如何在没有接口的情况下成功MOQ一个类?
我还不清楚如何在没有可用接口的情况下使用依赖注入:
private FileInfo _logFile;
public LogEventProcessorTextFile(FileInfo logFile) {
_logFile = logFile;
}
Run Code Online (Sandbox Code Playgroud)
当我真的想做这样的事情时(注意IFileInfo而不是FileInfo):
private IFileInfo _logFile;
public LogEventProcessorTextFile(IFileInfo logFile) {
_logFile = logFile;
}
Run Code Online (Sandbox Code Playgroud) 我正在使用NHibernate,ASP.NET MVC 2.0和StructureMap开始一个新项目,并使用NUnit和Moq进行测试.对于我的每个控制器,我都有一个公共构造函数,其中注入了一个ISession.应用程序本身工作正常,但就单元测试而言,我基本上必须模拟一个ISession才能测试控制器.
当我尝试使用MOQ模拟ISession时,我收到以下错误消息:
中间调用仅支持属性访问
看来我的问题是期待来自框架CreateQuery方法的用户列表,但在谷歌搜索问题之后我现在更清楚了.
我有两个问题:
1)这是模拟依赖注入ISession的错误方法吗?
2)有没有办法修改代码,以便它可以成功返回我的列表
[Test]
public void DummyTest()
{
var mock = new Mock<ISession>();
var loc = new Mock<User>();
loc.SetupGet(x => x.ID).Returns(2);
loc.SetupGet(x => x.FirstName).Returns("John");
loc.SetupGet(x => x.LastName).Returns("Peterson");
var lst = new List<User> {loc.Object};
mock.Setup(framework => framework.CreateQuery("from User").List<User>()).Returns(lst);
var controller = new UsersController(mock.Object);
var result = controller.Index() as ViewResult;
Assert.IsNotNull(result.ViewData);
}
Run Code Online (Sandbox Code Playgroud)
请注意,我很确定我可以创建一个硬编码的用户列表(而不是模拟单个用户并将其添加到列表中),但我想我现在已经保留了代码.
此外,此特定控制器的Index操作基本上执行上面模仿的CreateQuery调用以返回数据库中的所有用户.这是一个人为的例子 - 不要读任何细节.
在此先感谢您的帮助
编辑:在回复以下评论时,我正在添加错误的堆栈跟踪.此外,User类上的所有属性都是虚拟的.
TestCase'Beta.Tests.Unit.Controllers.UserControllerTest.Details_InValidIndex_ReturnsNotFoundView'失败:System.NotSupportedException:在设置的中间调用中仅支持属性访问.不支持的表达式framework.CreateQuery("来自用户").位于Moq.Mock.AutoMockPropertiesVisitor的Moq.ExpressionVisitor.Visit(表达式exp)Moq.Mock.AutoMockPropertiesVisitor.VisitMethodCall(MethodCallExpression m)的Moq.Exkression.Vatitor上的Moq.Mock.AutoMockPropertiesVisitor.VisitMethodCall(MethodCallExpression m)中的Moq.Mock.AutoMockPropertiesVisitor.VisitMethodCall(MethodCallExpression m) Moq.Mock上的Moq.Mock.GetInterceptor(LambdaExpression lambda,Mock mock)的.SetupMocks(表达式表达式).<> c__DisplayClass12
2.<Setup>b__11() at Moq.PexProtector.Invoke[T](Func1函数)在Moq.Mock.Setup [T1,TResult](模拟模拟,表达式1 expression) at Moq.Mock1.Setup …
我目前对如何嘲笑感到困惑.
我正在使用Moq.为了模拟对象,我通常以这种方式编写
var mockIRepo = new Mock<IRepo>();
Run Code Online (Sandbox Code Playgroud)
但是,我需要为我的设置创建模拟对象.
Option1 以这种方式模拟仅包含属性的对象是否更好?
var object = Mock.Of<Object>()
Run Code Online (Sandbox Code Playgroud)
Option2 或者这样
var object = new Mock<Object>()
Run Code Online (Sandbox Code Playgroud)
我已经读过选项2有setupproperties这对我来说有点问题,因为我也可以在选项1中设置属性.
那有什么区别?或者,还有更好的方法?
什么是在AutoMapper中为Map函数设置模拟预览的最佳方法.
我提取IMapper接口,以便我可以设置该接口的预期.我的映射器有依赖关系,所以我必须将它们传递给映射器.
当我创建2个mapper类实例时会发生什么,有2个不同的依赖实现?我认为两个映射器将使用相同的依赖项实例,因为AutoMapper映射是静态的.或者AutoMapper甚至可能会抛出异常,因为我尝试使用相同的对象设置2个不同的地图.
什么是解决这个问题的最佳方法?
public interface IMapper {
TTarget Map<TSource, TTarget>(TSource source);
void ValidateMappingConfiguration();
}
public class MyMapper : IMapper {
private readonly IMyService service;
public MyMapper(IMyService service) {
this.service = service
Mapper.CreateMap<MyModelClass, MyDTO>()
.ForMember(d => d.RelatedData, o => o.MapFrom(s =>
service.getData(s.id).RelatedData))
}
public void ValidateMappingConfiguration() {
Mapper.AssertConfigurationIsValid();
}
public TTarget Map<TSource, TTarget>(TSource source) {
return Mapper.Map<TSource, TTarget>(source);
}
}
Run Code Online (Sandbox Code Playgroud) 我找不到在Moq中使用When方法的示例
When(Func<bool> condition);
Run Code Online (Sandbox Code Playgroud)
该方法的目的/用途是什么?请提供一个代码示例,演示一个有用的场景.
是否可以根据输入返回不同的结果,如
MoqSecurityAdminHelper.Setup(x => x.GetAllQuestions(It.IsAny<Boolean>()))
.Returns(new Dictionary<String, String>
{
{"Key1", "Value1"},
{"Key2", "Value2"}
});
Run Code Online (Sandbox Code Playgroud)
但如果参数为true,则返回一个结果,如果为false则返回另一个结果.
或者是唯一的方法来进行2个单独的设置?
谢谢
我有一对父/子关系的表 - 事件和事件详细信息.我有一个viewmodel,包含来自这两个表的信息.我有一个业务层方法,它传递一个需要更新两个表的viewmodel实例.
所以,在这个方法中,我使用EF6的新事务机制:
using (var transaction = this.db.Database.BeginTransaction())
{
try
{
// various database stuff
this.db.SaveChanges();
// more database stuff
this.db.SaveChanges();
// yet more database stuff
this.db.SaveChanges();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
this.logger.logException(ex, "Exception caught in transaction, rolling back");
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题.我该如何测试?
我正在使用微软的单元测试框架,使用Moq,我在模拟DBContexts和DbSet <>时没有遇到任何麻烦,但我似乎无法弄清楚如何绕过事务的东西.
如果我不尝试模拟事务,我会得到一个InvalidOperationException:
"在应用程序配置文件中找不到名为xxx的连接字符串."
这很有道理 - 没有应用程序配置文件,也没有任何数据库.
但是如果我尝试模拟BeginTransaction(),我会得到初始化错误:NotSupportedException:
"非虚拟成员的设置无效:m => m.Database.BeginTransaction".
这让我追逐杂草,看着.NET方法的反编译,试图找出一些可能来自可用接口的类,或者某些东西,我可以以某种方式注入一个模拟对象.
我不是要对MS的事务代码进行单元测试 - 我只是想确保对每个表中的相应记录进行适当的更改.但就其而言,它看起来像是不可测试的,并且任何使用事务的方法都是不可测试的.这只是一种痛苦.
我用Google搜索过,没有发现任何有用的东西.有没有人遇到过这个问题?任何人都有关于如何进行的想法?
由于某种原因,此代码一直在失败.任何可以告诉我原因的人:
var activeLoans = new List<ActiveLoan> {
new ActiveLoan{
ID = 1,
CaseType = "STL",
LoanCode = 0
},
new ActiveLoan{
ID = 2,
CaseType = "STL",
LoanCode = 0
},
new ActiveLoan{
ID = 3,
CaseType = "STL",
LoanCode = 0
}
}.AsQueryable();
var activeLoanMockSet = new Mock<DbSet<ActiveLoan>>();
activeLoanMockSet.As<IQueryable<ActiveLoan>>().Setup(m => m.Provider).Returns(activeLoans.Provider);
activeLoanMockSet.As<IQueryable<ActiveLoan>>().Setup(m => m.Expression).Returns(activeLoans.Expression);
activeLoanMockSet.As<IQueryable<ActiveLoan>>().Setup(m => m.ElementType).Returns(activeLoans.ElementType);
activeLoanMockSet.As<IQueryable<ActiveLoan>>().Setup(m => m.GetEnumerator()).Returns(activeLoans.GetEnumerator());
mockContext.Setup(c => c.ActiveLoans).Returns(activeLoanMockSet.Object);
// This is the line that fails
Assert.AreNotEqual(mockContext.Object.ActiveLoans.Find( 1 ), null);
Run Code Online (Sandbox Code Playgroud)
当我说失败时,我的意思是单元测试这是失败的一部分.
我正在开发一个尝试使用此示例实现MVP模式的asp.net(经典)应用程序.在尝试对我的演示者进行单元测试并使用以下模式时,psuedocode看起来像这样
//base view interface
public interface IView
{
event EventHandler Init;
event EventHandler Load;
bool IsPostBack { get; }
void DataBind();
bool IsValid { get;}
}
//presenter psuedo code
public class SomePresenter
{
public SomePresenter(ISomeDomainService service, IView someView)
{
...
//HOW DO WE TEST/VERIFY THAT THIS REGISTRATION OCCURS?
someView.Init += OnInit;
someView.Load += OnLoad;
}
}
...
//consuming code that exercises the above code, that needs to be tested
var presenter = new SomePresenter(someDomainService, someView);
Run Code Online (Sandbox Code Playgroud)
如何验证演示者是否正在执行预期的操作,即注册Init和Load事件?虽然这很容易在Phil Haack …
我有这样一组构造函数:
public BusinessObjectContext()
: this(CloudStorageAccount.FromConfigurationSetting("DataConnectionString").TableEndpoint.ToString(),
CloudStorageAccount.FromConfigurationSetting("DataConnectionString").Credentials) {}
public BusinessObjectContext(string dataConnectionString)
: this(CloudStorageAccount.Parse(dataConnectionString).TableEndpoint.ToString(),
CloudStorageAccount.Parse(dataConnectionString).Credentials) { }
public BusinessObjectContext(String baseAddress, StorageCredentials credentials)
: base(baseAddress, credentials) { }
Run Code Online (Sandbox Code Playgroud)
但是在测试/模拟时我需要没有任何连接字符串参数的对象.我怎么能这样做 - 最好是在Moq?
这有可能吗?
moq ×10
c# ×9
unit-testing ×7
.net ×4
asp.net ×1
automapper ×1
constructor ×1
interface ×1
lambda ×1
mocking ×1
nhibernate ×1
testing ×1