我对这两个库都是新手,在承诺在大型项目中使用它们之前,我需要澄清我在单元测试中自动锁定低代码工作的选项。
在Google上花了一段时间之后,我得出的结论是,与其他国际奥委会/模仿产品配对不同的是,LightInject+Nsubstitute没有现成的插件库来简化单元测试安排阶段的无事默认模拟的声明。
我已经阅读了LightInject文档中关于如何为单元测试的作用域覆盖一个临时增强的模拟对象的LightInject容器的文档,但是单元测试可能触及的所有未做任何默认隔离模拟怎么办?有没有一种方法可以在LightInject容器中自动创建它们?
我要寻找的内部IOC容器行为是:
public class LightInject.ServiceContainer
{
..
public T GetInstance<T)
{
if (( this.RegisteredInterfaces.Any( i => i.Itype == T ) == false )
&& ( this.TemporaryUnitTestOverrides.Any( i => i.Itype == T ) == false ))
&& ( /* this container is configured with an automocking delegate */ ))
return autoMockCreatorDelegate<T>.Invoke();
}看起来,LightInject的IProxy和拦截器提供了一些内部模拟对象构建块,但与之相比,N替代库功能齐全。
在默认情况下,澄清我的意思,不做模拟和增强的模拟。
// default do nothing mock
var calculator = Substitute.For<ICalculator>();
// Enhanced mock that will return 3 for .Add(1,2)
var calculator = Substitute.For<ICalculator>();
calculator.Add(1, 2).Returns(3);显然,每个单元测试都需要在本地构建第二种增强的模拟类型。
发布于 2014-05-04 08:56:34
我是LightInject的作者,很想帮你解决这个问题。
让我调查一下,然后再联系你。同时,您可能希望在LightInject.AutopMoq上签出这个库,这是对LightInject容器的第三方贡献。它使用的是Moq而不是NSubstitute,但是一般的概念应该与您所要求的类似。
尽管如此,不久前我做了一些工作,进一步简化了自动锁定,并将对其进行研究,看看如何将其集成到NSubstitute中。
编辑
这是一个超级简单的自动锁定实现,可以与任何“替代”框架一起工作。
using System.Diagnostics;
using LightInject;
using NSubstitute;
public interface IFoo { }
class Program
{
static void Main(string[] args)
{
var serviceContainer = new ServiceContainer();
serviceContainer.RegisterFallback((type, s) => true, request => CreateMock(request.ServiceType));
var foo = serviceContainer.GetInstance<IFoo>();
Debug.Assert(foo is IFoo);
}
private static object CreateMock(Type serviceType)
{
return Substitute.For(new Type[] { serviceType }, null);
}
}诚挚的问候
伯恩哈德里克特
发布于 2014-05-08 09:54:17
一些反馈意见,如我在评论中承诺接受的答案。我在一些简单的单元测试中成功地应用了LightInject作者的建议。
在完成了基础工作之后,我决定将Ioc服务模拟安装代码隐藏在一个基类中,再加上我称之为MockingContext的东西,最终结果是更干净、更轻的单元测试代码。模拟上下文类还确保了作为短期自动覆盖传递给Ioc服务的foreachN替代品配置的模拟类型,有一个匹配的LightInjet.Service.EndMocking( T)调用。这消除了配置的模拟可能会污染以下单元测试的自动模拟假设的危险。
在示例中,ClassC依赖于IFooA和IFooB (没有构造函数注入)。对于下面的单元测试,IFooA在没有显式代码的情况下由LightInject自动模拟,而IFooB是通过一个N替代调用配置的,并在MockingContext.Add<>()方法中传递给LightInject。
[TestClass]
public class UnitTest1 : AutoMocking
{
[TestMethod]
public void Test_1()
{
using (var mc = MockingContext)
{
// No need to mention IFooA here, LightInject will auto mock
// any interface not previously declared to it.
// Given
var mockB = mc.Add<IFooB>();
mockB.MethodY().Returns("Mock Value OOO");
var sut = new ClassC();
// When
var testResult = sut.MethodZ();
// Then
Assert.AreEqual(testResult, "MethodZ() received=Mock Value OOO");
}
}https://stackoverflow.com/questions/23445099
复制相似问题