所以我尝试在ASP.NET MVC 5中使用Automocking,但由于某些原因,我无法让它工作。
到目前为止,这是一个测试:
using (var mock = AutoMock.GetLoose())
{
const string mainUserID = "MainUserID";
const string otherUserID = "OtherUserID";
ApplicationUser user = new ApplicationUser()
{
Id = mainUserID,
UserName = "TestUser"
};
var dataProvider = mock.Mock<IDataProtectionProvider>();
dataProvider.DefaultValue = DefaultValue.Mock;
var userManagerMock = mock.Mock<ApplicationUserManager>();
}当模拟ApplicationUserManager时,测试失败。错误是:
Result StackTrace:
at Autofac.Extras.Moq.AutoMock.Mock[T](Parameter[] parameters)
at AwenterWeb_NUnit.AccountControllerTest.<Deactivate_User>d__0.MoveNext() in C:\Users\Fabis\Documents\Docs\Kvalifikācijas darbs 2015\AwenterWeb\AwenterWeb-NUnit\AccountControllerTest.cs:line 51
at NUnit.Framework.AsyncInvocationRegion.AsyncTaskInvocationRegion.WaitForPendingOperationsToComplete(Object invocationResult)
at NUnit.Core.NUnitAsyncTestMethod.RunTestMethod()
Result Message: System.InvalidCastException : Unable to cast object of type 'AwenterWeb.ApplicationUserManager' to type 'Moq.IMocked`1[AwenterWeb.ApplicationUserManager]'.同样的事情发生在试图自动化ApplicationDbContext时,它有一个非常简单的构造函数,所以它甚至不应该有任何问题。我刚开始嘲笑-在这种情况下我该怎么做?
编辑:这也是一个不相关的问题,也许你们知道--我注意到当使用测试中先前创建的列表为DbSet创建一个Moq时,我必须这样做:
var dbSetMock = new Mock<IDbSet<DbEntity>>();
dbSetMock.Setup(m => m.Provider).Returns(data.Provider);
dbSetMock.Setup(m => m.Expression).Returns(data.Expression);
dbSetMock.Setup(m => m.ElementType).Returns(data.ElementType);
dbSetMock.Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());这似乎是不直观的。有办法让模拟人拿走名单吗?所以,就像:
dbSetMock.Setup(m => m).Returns(data);或者任何其他方法可以快速从现有列表中创建DbSet Moq,而无需编写这4行额外的行?
发布于 2015-05-19 14:23:25
如果您查看MoqRegistrationHandler.cs的Lenge73,您可以看到只有使用Autofac.Extras.Moq的接口是可移动的。
var typedService = service as TypedService;
if (typedService == null ||
!typedService.ServiceType.IsInterface ||
typedService.ServiceType.IsGenericType && typedService.ServiceType.GetGenericTypeDefinition() == typeof(IEnumerable<>) ||
typedService.ServiceType.IsArray ||
typeof(IStartable).IsAssignableFrom(typedService.ServiceType))
return Enumerable.Empty<IComponentRegistration>();
var rb = RegistrationBuilder.ForDelegate((c, p) => CreateMock(c, typedService))
.As(service)
.InstancePerLifetimeScope(); 您可以更改代码,但要使其在非参数依赖性较低的情况下工作可能非常困难。
可以将依赖项更改为使用接口而不是具体的类吗?如果这是不可能的和/或没有意义的,您可以使用MockRepository来创建非参数的无参数组件,然后将它注入到AutoMock类中。
class Program
{
static void Main(string[] args)
{
using (var mock = AutoMock.GetLoose())
{
/// configure your non interface component with constructor parameters
/// if foo need more complex parameters you can get them
/// using mock.Mock<T>().Object
var fooMock = mock.MockRepository.Create<Foo>((String)null);
fooMock.SetupGet(f => f.Value).Returns("test");
// insert your instance into the container
mock.Provide<Foo>(fooMock.Object);
var bar = mock.Create<Bar>();
Console.WriteLine(bar.GetValue());
}
}
}
public class Foo
{
public Foo(String value)
{
this._value = value;
}
private readonly String _value;
public virtual String Value
{
get
{
return this._value;
}
}
}
public interface IBar
{
String GetValue();
}
public class Bar : IBar
{
public Bar(Foo foo)
{
this._foo = foo;
}
private readonly Foo _foo;
public String GetValue()
{
return this._foo.Value;
}
}这不是一个完美的解决方案,但是如果不对Autofac.Extras.Moq项目进行大规模重构,我就找不到更简单的方法了。
https://stackoverflow.com/questions/30313047
复制相似问题