2010-11-10 56 views
2

我有一個公開接口WCF數據服務:嘲諷WCF客戶的IQueryable成員

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:該DataServiceContext到的DataServiceCollection實例所屬的可能不確定。該DataServiceContext必須要麼在構造函數中的DataServiceCollection提供或用於創建化DataServiceQuery或QueryOperationResponse對象,它是項目中的DataServiceCollection

源這似乎是越來越複雜。有沒有辦法讓Visual Studio生成帳戶&合同的接口或讓accts.Contracts返回IQueryable<Contract>而不是DataServiceCollection<Contract>?也許一些其他簡單的解決方案來嘲笑這項服務?


爲了清楚起見,svcutil.exe的是生成一個賬戶類,它看起來是這樣的:

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; } 
} 

回答

-1

由於Contracts屬性是IEnumerable類型,你可以創建任何枚舉集合。

所以,與其

Contracts = new DataServiceCollection<Contract>(blah) 

只使用

Contracts = new [] { blah } 

這將確保你會在你僞裝的對象被斷開。

+0

這似乎是一個不錯的主意,但在生成的代碼合同屬性的類型DataServicesCollection 的。如果我可以讓VS生成一個IAccount接口,DataServicesCollection的確擴展IEnumerable 。我仍然沒有看到讓生成的代碼實現接口 – kelloti 2010-11-11 15:52:43

+0

@kelloti的方法:不,它不是。 Dmytrii不喜歡我的答案,即使他和我的答案基本相同:他們基於這樣一個事實,即Contracts屬性是一個「IEnumerable 」,至少是您向我們顯示的代碼。 – rsenna 2010-11-11 17:39:52

5

對於那些通過搜索引擎發現此問題的人。

要在手動創建DataServiceCollection時消除「DataServiceContext ... could not be determined」異常,請使用overloaded constructor並將TrackingMode參數設置爲None。

即,

new DataServiceCollection<Contract>(blah, TrackingMode.None)