question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Workaround for unit testing and CosmosLinqQuery<T>

See original GitHub issue

Is 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:open
  • Created 4 years ago
  • Reactions:25
  • Comments:17 (3 by maintainers)

github_iconTop GitHub Comments

20reactions
ryazan05commented, Dec 2, 2019

@TechWatching Yes. You will need to implement ICosmosLinqQuery mentioned above. Implementation is just a call to return FeedIterator:

public class MyCosmosLinqQuery : ICosmosLinqQuery
{
   public FeedIterator<T> GetFeedIterator<T>(IQueryable<T> query)
   {
      return query.ToFeedIterator();
   }
}

Then in your code instead of calling ToFeedIterator directly, inject ICosmosLinqQuery implementation and use that to get feedIterator:

var query = _myContainer.GetItemLinqQueryable<MyClass>()
                                               .Where(t => t.MyProperty == id);

var feedIterator = _myCosmosLinqQuery.GetFeedIterator(query);

while (feedIterator.HasMoreResults)
{
   foreach (var result in await feedIterator.ReadNextAsync())
   {
      yield return result;
   }
}

In unit tests you can assert on linq query. Moq example:

...
IQueryable<MyClass> queryResult = null;
var mockCosmosLinqQuery = new Mock<ICosmosLinqQuery>();
mockCosmosLinqQuery.Setup(x => x.GetFeedIterator(...))
   .Callback<IQueryable<MyClass>>(r => queryResult = r)
   .Returns(...);
...
Assert.True(queryResult.All(x => x.MyProperty == expectedId));
10reactions
danielwcrcommented, Jan 27, 2021

Same old issue with ms sdks. I wonder if ms will ever be able to provide a testable client.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Visual Studio: Unit Testing a web project in the same solution
I have a solution with a WebAPI project and a VS Test project. My tests make calls to the API using RestSharp via...
Read more >
Unit Testing and Coding: Why Testable Code Matters
In this article, I will show that unit testing itself is quite easy; the real problems that complicate unit testing, and introduce expensive...
Read more >
Unit testing C# code in .NET Core using dotnet test and xUnit
Open a shell window. The dotnet new sln command creates a new solution in the unit-testing-using-dotnet-test directory. Change directory to the ...
Read more >
Unit Testing Tutorial: 6 Best Practices to Get Up To Speed
Improving Code Quality: Unit testing can help improve code quality by ensuring that each unit of code is functioning correctly and as expected....
Read more >
Unit Testing: Definition, Examples, and Critical Best Practices
Unit testing and results—finally, the unit test runs and developers can identify errors or issues in the code and fix them.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found