Son*_*oul 5 dependency-injection castle-windsor moq ioc-container
\n\n\n版本 \xc2\xa0\xc2\xa0 温莎城堡 3.3.0.0 \xc2\xa0\xc2\xa0 起订量 4.2.1507.118
\n
看来 Moq 附带了CallBase设置,启用后,会将对任何非设置方法的调用委托给基础对象。
\n\nvar mock = new Mock<MyService> {CallBase = true};\nRun Code Online (Sandbox Code Playgroud)\n\n不幸的是,一旦我向温莎城堡注册它,所有非模拟方法都会立即返回 null,不再调用底层逻辑。
\n\n Container.Register(Component\n .For<MyService>()\n .Instance(mock.Object)\n .LifeStyle.Singleton\n );\nRun Code Online (Sandbox Code Playgroud)\n\n我也尝试了几种不同的生活方式。
\n\n所以当我这样做时:
\n\nmock.setup(x => x.SomeMethod).Returns(myMockedData);\nRun Code Online (Sandbox Code Playgroud)\n\n这按预期工作:
\n\nContainer.Resolve<MyService>().SomeMethod();\nRun Code Online (Sandbox Code Playgroud)\n\n但现在返回一个空值:
\n\nContainer.Resolve<MyService>().AnotherMethod(); \nRun Code Online (Sandbox Code Playgroud)\n\n一旦我删除模拟注册, AnotherMethod 就会像以前一样开始工作。
\n\n更具体的代码示例
\n\npublic class Auth : IAuth\n{\n // mocked succesfully\n public IEnumerable<T> AuthorizeData<T>(IEnumerable<T> data) { ... }\n\n // never gets called\n public virtual List<User> GetAllUsers() {\n return new List<User>{new User{FIRST_NAME = "test"}};\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n模拟方法
\n\n protected static Mock<T> GetMock<T>() where T : class {\n\n var mock = new Mock<T> {CallBase = true, DefaultValue = DefaultValue.Mock};\n IoC.Container.Register(Component\n .For<T>()\n .Instance(mock.Object)\n .LifeStyle.Transient\n );\n return mock;\n }\nRun Code Online (Sandbox Code Playgroud)\n\n模拟设置
\n\nGetMock<IAuth>().Setup(x => x.AuthorizeData(It.IsAny<IEnumerable<DO>>()))\n .Returns((IEnumerable<DO> data) => data); // pass through input data (do not authorize\nRun Code Online (Sandbox Code Playgroud)\n\n再次总结一下,AuthorizeData被mock成功,GetAllUsers()返回一个空列表。原来的类永远不会被调用
\nCallBase不控制返回值的生成方式。为此,您需要设置DefaultValue属性:
var mock = new Mock<MyService> { CallBase = true, DefaultValue = DefaultValue.Mock };
Run Code Online (Sandbox Code Playgroud)
DefaultValue(原文如此)的默认值是DefaultValue.Empty,因此这就是您需要将其显式设置为 的原因DefaultValue.Mock。
当您这样做时,mock将从方法中返回其他代理值,而无需显式设置。如果返回值是具体类型,Moq 将尝试创建该类型的值,但只有在该类型具有无参数构造函数时才会这样做。如果不存在无参数构造函数,当您尝试调用该方法时,它将抛出异常。
您可能想考虑将温莎城堡变成自动模拟容器。
根据下面的评论,我无法重现该问题。假设AuthorizeData是这样virtual(上面没有,但评论声称),这个测试通过了:
[Fact]
public void Repro()
{
var td = new Mock<Auth>
{
CallBase = true,
DefaultValue = DefaultValue.Mock
};
var container = new WindsorContainer();
container.Register(Component.For<Auth>().Instance(td.Object));
td
.Setup(a => a.AuthorizeData<string>(new string[0]))
.Returns(new[] { "foo", "bar" });
Assert.Equal(
new[] { "foo", "bar" },
container.Resolve<Auth>().AuthorizeData(new string[0]));
Assert.NotEmpty(container.Resolve<Auth>().GetAllUsers());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1897 次 |
| 最近记录: |