Как имитировать пакетный ответ из OData DataServiceContextC#

Место общения программистов C#
Ответить
Anonymous
 Как имитировать пакетный ответ из OData DataServiceContext

Сообщение Anonymous »

Я пишу модульные тесты для проекта .NET FW 4.8, который подключается к API с помощью библиотеки OData.net. Проект использует DataServiceContext для отправки пакетных запросов и получения ответов. Чтобы протестировать этот проект, я хочу имитировать пакетные ответы, которые возвращаются в DataServiceContext.
Я перенес некоторый код модульного теста из официального репозитория OData.net Github, и я могу имитировать ответы на непакетные запросы GET и PATCH, но у меня возникают проблемы с имитированием пакетных запросов, содержащих операции PATCH. Ниже приведен рабочий модульный тест, имитирующий непакетированные ответы.

Код: Выделить всё

    [TestMethod]
public void Update_Test()
{
DataServiceContext mockContext = new DataServiceContext(new Uri(Constants.BASE_URI));
mockContext.Format.UseJson(Utils.BuildEdmModel());
mockContext.MergeOption = MergeOption.PreserveChanges;

var salesOrdersQuery = mockContext.CreateQuery(Constants.SALES_ORDERS_SET_NAME);

// Setup a GET request to fake
string resp = Utils.LoadJsonPayload("GET_SalesOrderWithLineResp.json");
Utils.MockQueryResponse(
context: mockContext,
baseUriStr: Constants.BASE_URI,
entitySetName: Constants.SALES_ORDERS_SET_NAME,
mockResponseValue: resp
);

// GET faked order, then update
MockSalesOrder order = salesOrdersQuery.Expand(o => o.SalesOrderLines).First();
order.OrderType = "Return";
mockContext.UpdateObject(order);

// Setup a PATCH request to fake
resp = Utils.LoadJsonPayload("PATCH_SalesOrderWithLineResp.json");
Utils.MockSaveResponse(
context: mockContext,
location: string.Format("{0}/SalesOrders(OrderNo='S-ORD100000',OrderType='Order')", Constants.BASE_URI),
response: resp
);

// Fake a PATCH request
mockContext.SaveChanges();
}
Методы MockQueryResponse и MockSaveResponse были взяты из проекта OData и определены как:

Код: Выделить всё

public static void MockQueryResponse(DataServiceContext context, string baseUriStr, string entitySetName, string mockResponseValue)
{
string mockResponse = "{\"@odata.context\":\"" + baseUriStr + "/$metadata#" + entitySetName + "\",\"value\":" + mockResponseValue + "}";
context.ResolveName = (type) => $"NS.{type.Name}";
context.Configurations.RequestPipeline.OnMessageCreating = (args) =>
{
var contentTypeHeader = "application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8";
var odataVersionHeader = "4.0";

return new TestHttpWebRequestMessage(args,
new Dictionary
{
{"Content-Type", contentTypeHeader},
{"OData-Version", odataVersionHeader},
},
() =>  new MemoryStream(Encoding.UTF8.GetBytes(mockResponse)));
};
}

public static void MockSaveResponse(DataServiceContext context, string location, string response)
{
context.Configurations.RequestPipeline.OnMessageCreating = (args) =>
{
return new CustomizedRequestMessage(
args,
response,
new Dictionary()
{
{"Content-Type", "application/json;charset=utf-8"},
{ "Location", location },
});
};
}
Для дальнейшего использования ложный ответ GET определяется как:

Код: Выделить всё

[
{
"OrderNo": "S-ORD100000",
"OrderType": "Order",
"SampleField": "Test",
"SalesOrderLines": [
{
"OrderNo": "S-ORD100000",
"OrderType": "Order",
"LineNo": "1000",
"SampleField": "Test"
}
]
}
]
и ложный ответ PATCH:

Код: Выделить всё

{
"@odata.context": "https://mock.odata.service/$metadata#SalesOrders/$entity",
"@odata.editLink": "http://https//mock.odata.service/SalesOrders(OrderNo='S-ORD100000',OrderType='Order')",
"@odata.etag": "W/\"JzE5OzY4MjIzMTYxNjY4MTkyNDY2MDgxazAwOyc=\"",
"OrderNo": "S-ORD100000",
"OrderType": "Order",
"SampleField": "Test",
"SalesOrderLines": [
{
"@odata.etag": "W/\"JzE5OzY4MjIzMTYxNjY4MTkyNDY2MDgxOzAwOyc=\"",
"OrderNo": "S-ORD100000",
"OrderType": "Order",
"LineNo": "1000",
"SampleField": "Test"
}
]
}
Предыдущий код и ответы работают нормально, но если я обновлю содержимое ответа до пакетного ответа и установлю SaveChangeOptions в вызове SaveChanges, я получу следующую ошибку:

Код: Выделить всё

   System.NotSupportedException: 'Memory stream is not expandable.'
at System.IO.__Error.MemoryStreamNotExpandable()
at System.IO.MemoryStream.set_Capacity(Int32 value)
at System.IO.MemoryStream.EnsureCapacity(Int32 value)
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at Microsoft.OData.Client.ODataRequestMessageWrapper.SetRequestStream(ContentStream requestStreamContent)
at Microsoft.OData.Client.BatchSaveResult.BatchRequest()
at Microsoft.OData.Client.DataServiceContext.SaveChanges(SaveChangesOptions options)
Обновленный вызов SaveChanges для пакетного запроса:

Код: Выделить всё

mockContext.SaveChanges(SaveChangesOptions.BatchWithIndependentOperations | SaveChangesOptions.UseRelativeUri);
И ложный пакетный ответ:

Код: Выделить всё

{
"responses": [
{
"id": "1",
"status": 200,
"headers": {
"content-type": "application/json; odata.metadata=minimal; odata.streaming=true",
"odata-version": "4.0"
},
"body": {
"@odata.context": "https://mock.odata.service/$metadata#SalesOrders/$entity",
"@odata.etag": "W/\"JzE5OzczMTExMDYxMjE3NTYxMzY5MjkxOzAwOyc=\"",
"OrderNo": "S-ORD100000",
"OrderType": "Order",
"SampleField": "Test"
}
}
]
}
Я не понимаю причины этой ошибки. Любые идеи или предложения по решению этой проблемы будут очень признательны. Спасибо!

Подробнее здесь: https://stackoverflow.com/questions/791 ... icecontext
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»