2010-11-10 4 views
2

У меня есть службы данных WCF, который предоставляет интерфейсы:Mocking 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: DataServiceContext, к которой принадлежит экземпляр DataServiceCollection может не определяется. DataServiceContext должны либо поставляться в конструкторе DataServiceCollection или использоваться для создания объекта DataServiceQuery или QueryOperationResponse, который является источником элементов в DataServiceCollection

Это кажется, что это становится очень сложным. Есть ли способ просто создавать интерфейсы Visual Studio для учетной записи & Контракт или иметь 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; } 
} 

ответ

-1

Как Contracts свойства типа IEnumerable, вы можете создать любые перечислимые коллекции.

Таким образом, вместо

Contracts = new DataServiceCollection<Contract>(blah) 

просто использовать

Contracts = new [] { blah } 

Это обеспечит вам будут отключены в ваших поддельных объектах.

+0

Это кажется хорошей идеей, за исключением того, что в сгенерированном коде свойство контрактов типа DataServicesCollection . Если бы я мог заставить VS создать интерфейс IAccount, DataServicesCollection расширяет IEnumerable . Я до сих пор не видел способ создания сгенерированного кода интерфейса – kelloti

+0

@kelloti: нет, это не так. Dmytrii мне не понравился, даже если его и мои в основном одинаковы: они основаны на том факте, что свойство Contracts является «IEnumerable », по крайней мере по коду, который вы нам показали. – rsenna

5

Для тех, кто нашел этот вопрос в поисковой системе.

Чтобы исключить исключение «DataServiceContext ... не может быть определено» при ручном создании DataServiceCollection, используйте параметр overloaded constructor с параметром TrackingMode равным None.

есть,

new DataServiceCollection<Contract>(blah, TrackingMode.None) 
Смежные вопросы