作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
为什么TargetInvocationException
mock ChannelFactory<IService>
时抛出?
public interface IService
{
void Do();
}
public class Service : IService
{
private ChannelFactory<IRemoteService> factory;
public Service(ChannelFactory<IRemoteService> factory)
{
this.factory = factory;
}
public void Do()
{
using (var remote = factory.CreateChannel())
{
remote.DoRemote();
}
}
}
[TestFixture]
public class ChannelFactoryMoqTest
{
private IService service;
private Mock<ChannelFactory<IRemoteService>> factory;
[Test]
public void Test()
{
this.factory = new Mock<ChannelFactory<IRemoteService>>();
this.service = new Service(this.factory.Object);
// Calling Object on this.factory throws TargetInvocationException
}
}
我想使用ChannelFactory
依赖而不是简单的 IRemoteService
因为在我看来,在并发性方面创建 Service
更安全每次调用实例。
这是异常堆栈跟踪:
System.Reflection.TargetInvocationException was unhandled by user code
HResult=-2146232828
Message=Exception has been thrown by the target of an invocation.
Source=mscorlib
StackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, Object[] args)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
at Moq.Proxy.CastleProxyFactory.CreateProxy(Type mockType, ICallInterceptor interceptor, Type[] interfaces, Object[] arguments)
at Moq.Mock`1.<InitializeInstance>b__2()
at Moq.PexProtector.Invoke(Action action)
at Moq.Mock`1.InitializeInstance()
at Moq.Mock`1.OnGetObject()
at Moq.Mock.GetObject()
at Moq.Mock.get_Object()
at Moq.Mock`1.get_Object()
at TR.Eikon.Services.AppVersion.Tests.Workflows.ChannelFactoryMoqTest.Test() in d:\Temp.cs:line 61
InnerException: System.NullReferenceException
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=System.ServiceModel
StackTrace:
at System.ServiceModel.ChannelFactory.EnsureSecurityCredentialsManager(ServiceEndpoint endpoint)
at System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName, EndpointAddress address)
at System.ServiceModel.ChannelFactory`1..ctor()
at Castle.Proxies.ChannelFactory`1Proxy..ctor(IInterceptor[] )
InnerException:
最佳答案
您收到该错误是因为 ChannelFactory
正在尝试创建与其关联的非现有端点的实际代理。
我的建议是隐藏/隔离 ChannelFactory<IRemoteService>
从您控制的接口(interface)背后的客户端,以便您可以更好地管理您想要的 API。通过这种方式,您可以替换工厂,为客户端提供创建模拟而不是真实代理的工厂。
public interface IMyChannelFactory<TChannel> {
TChannel CreateChannel();
}
...稍后可以包装 ChannelFactory<IRemoteService>
的实际实例...
public class ChannelFactoryWrapper<TChannel> : IMyChannelFactory<TChannel> {
private ChannelFactory<TChannel> factory;
public ChannelFactoryWrapper(ChannelFactory<TChannel> factory) {
this.factory = factory;
}
public TChannel CreateChannel() {
return factory.CreateChannel();
}
}
您重构的服务类将引用您的新可模拟接口(interface)...
public class Service : IService {
private IMyChannelFactory<IRemoteService> factory;
public Service(IMyChannelFactory<IRemoteService> factory) {
this.factory = factory;
}
public void Do() {
using (var remote = factory.CreateChannel()) {
remote.DoRemote();
}
}
}
...然后您的测试可以进行相应的重构和测试...
[Test]
public void Should_Mock_ChannelFactory() {
//Arrange
var remoteService = new Mock<IRemoteService>();
remoteService.Setup(m => m.DoRemote()).Verifiable();
var factory = new Mock<IMyChannelFactory<IRemoteService>>();
factory.Setup(f => f.CreateChannel()).Returns(remoteService.Object).Verifiable();
var service = new Service(factory.Object);
//Act
service.Do();
//Assert
remoteService.Verify();
factory.Verify();
}
关于.net - 使用最小起订量模拟 ChannelFactory 时出现 TargetInitationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37410870/
我是一名优秀的程序员,十分优秀!