
[英]Mocking a WCF client, with a parameterised constructor for .net component called from COM
[英]Mocking WCF client's IQueryable members
我有一个公开接口的WCF数据服务:
public interface IAccountService
{
IQueryable<Account> Accounts { get; }
IQueryable<Contract> Contracts { get; }
}
[DataServiceKey("ID")]
public class Account
{
public virtual Guid ID { get; set; }
public virtual string AccountName { get; set; }
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
public virtual string Zip { get; set; }
public virtual string Phone { get; set; }
public virtual string Fax { get; set; }
public virtual string Status { get; set; }
public virtual DateTime StartDate { get; set; }
public virtual IEnumerable<Contract> Contracts { get; set; }
}
[DataServiceKey("ID")]
public class Contract
{
public virtual Guid ID { get; set; }
public virtual string ContractCode { get; set; }
public virtual string ContractName { get; set; }
public virtual DateTime StartDate { get; set; }
public virtual int UnitQty { get; set; }
public virtual double UnitPrice { get; set; }
}
我想模拟服务客户端进行单元测试。 我想写一个像这样的测试:
[Test]
public void MockContractsFromAccount()
{
var acctSvc = new Mock<IAccountService>();
var blah = new Contract[] { new Contract { ContractCode = "BLAH001", ContractName = "blah 1" },
new Contract { ContractCode = "BLAH002", ContractName = "blah 2" } };
var blee = new Contract[] { new Contract { ContractCode = "BLEE001", ContractName = "blee 1" } };
var accts = new Account[] { new Account { AccountName = "blah", State = "WY", Contracts = new DataServiceCollection<Contract>(blah) },
new Account { AccountName = "blee", State = "CO", Contracts = new DataServiceCollection<Contract>(blee) } };
acctSvc.SetupGet(x => x.Accounts).Returns(accts.AsQueryable());
var result = from x in acctSvc.Object.Accounts
where x.State == "CO"
select x;
Assert.That(result, Has.Count.EqualTo(1));
Assert.That(result.First().Contracts, Has.Count.EqualTo(2));
Assert.That(result, Is.All.EquivalentTo(blah));
}
但是代码在new DataServiceCollection<Contract>(blah)
失败并显示错误消息
SomeTests.MockContractsFromAccount:System.ArgumentException:无法确定DataServiceCollection实例所属的DataServiceContext。 必须在DataServiceCollection构造函数中提供DataServiceContext或将其用于创建DataServiceQuery或QueryOperationResponse对象,该对象是DataServiceCollection中各项的源
这似乎变得非常复杂。 有没有一种方法可以让Visual Studio为Account&Contract生成接口或获得accts.Contracts
返回一个IQueryable<Contract>
而不是DataServiceCollection<Contract>
? 也许还有其他简单的解决方案来模拟此服务?
为了清楚起见,svcUtil.exe生成了一个类似于以下内容的Account类:
public class Account
{
public Guid ID { get; set; }
public string AccountName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public string Status { get; set; }
public DateTime StartDate { get; set; }
// It descends from IEnumerable<Contract>
public DataServiceCollection<Contract> Contracts { get; set; }
}
对于那些通过搜索引擎发现此问题的人。
要消除手动创建DataServiceCollection时出现的“ DataServiceContext ...无法确定”异常,请使用TrackingMode参数设置为None的重载构造函数 。
也就是说,
new DataServiceCollection<Contract>(blah, TrackingMode.None)
由于Contracts
属性的类型为IEnumerable
,因此您可以创建任何可枚举的集合。
所以,代替
Contracts = new DataServiceCollection<Contract>(blah)
只是使用
Contracts = new [] { blah }
这将确保您在伪造的对象上断开连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.