Workaround for unit testing and CosmosLinqQuery<T>
See original GitHub issueIs your feature request related to a problem? Please describe.
I’ve written a method to obtain some values using a LinqQueryable
and then converting that via the extension method ToFeedIterator()
so it can be run asynchronously. It looks roughly like this:
var iterator = this.collection
.GetItemLinqQueryable<Thingie>()
.Where(thing => thing.x != "hello")
.ToFeedIterator();
if (iterator.HasMoreResults)
{
return (await iterator.ReadNextAsync()).FirstOrDefault();
}
Then in the unit test I make a mocked container return an EnumerableQuery<T>
when GetItemLinqQueryable<T>()
is called. This is so I can test the actual logic as part of the Linq query. It looks like this:
var samples = /* put some samples here */
var fakeContainer = Substitute.For<Container>();
fakeContainer
.GetItemLinqQueryable<T>()
.Returns(new EnumerableQuery<T>(samples));
The net result is hitting the exception about only supporting CosmosLinqQuery
instances:
Error Message:
System.ArgumentOutOfRangeException : ToFeedIterator is only supported on cosmos LINQ query operations
Parameter name: linqQuery
Stack Trace:
at Microsoft.Azure.Cosmos.Linq.CosmosLinqExtensions.ToFeedIterator[T](IQueryable`1 query)
Describe the solution you’d like I’m open to ideas that let us keep using Linq and writing unit tests.
The main immediate idea I have is exposing an interface or abstract version of CosmosLinuqQuery
. There are good reasons to not expose it I think though. So this might not be tractable.
Describe alternatives you’ve considered
I could fake out RequestHandler
’s in each scenario to work around this. That would make it easier to avoid the other cases where abstract classes or interfaces aren’t available. That would be a significant amount of work to do well though. So I’d prefer something else if it’s possible.
I could rewrite the code to not use Linq. That might be the route I go to keep making progress. We like using Linq when we can though and it does seem like it’s supported officially. So if we could keep doing this that would be nice.
I could skip building unit tests for this section and just focus on integration tests, but that’s generally not how we have done things everywhere else in the code. It would be much nicer if I could have support for both like we do today.
Additional context Thanks for the work on this!
Issue Analytics
- State:
- Created 4 years ago
- Reactions:25
- Comments:17 (3 by maintainers)
Top GitHub Comments
@TechWatching Yes. You will need to implement
ICosmosLinqQuery
mentioned above. Implementation is just a call to return FeedIterator:Then in your code instead of calling ToFeedIterator directly, inject ICosmosLinqQuery implementation and use that to get feedIterator:
In unit tests you can assert on linq query. Moq example:
Same old issue with ms sdks. I wonder if ms will ever be able to provide a testable client.