New to Telerik JustMock? Download free 30-day trial

Mocking LINQ Queries

This article provides practical examples that demonstrate how to mock LINQ queries with Telerik® JustMock and custom select.

This feature is available only in the commercial version of Telerik JustMock. Refer to this topic to learn more about the differences between the commercial and free versions of Telerik JustMock.

If you need a complete Visual Studio project that demonstrates how to mock LINQ queries, refer to our demo. The default installation directory is C:\Program Files (x86)\Progress\Telerik JustMock\Examples.

Prerequisites

In the further examples, we will use the following method and sample classes to test:

public class SimpleData 
{ 
    public ExtendedQuery<Product> Products 
    { 
        get 
        { 
            return null; 
        } 
    } 
 
    public ExtendedQuery<Category> Categories 
    { 
        get 
        { 
            return null; 
        } 
    } 
 
    public Product GetProduct( int id ) 
    { 
        return this.Products.Where( x => x.ProductID == id ).FirstOrDefault(); 
    } 
} 
 
public abstract class ExtendedQuery<T> : IEnumerable<T> 
{ 
    public IEnumerator<T> GetEnumerator() 
    { 
        throw new System.NotImplementedException(); 
    } 
 
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
        throw new System.NotImplementedException(); 
    } 
} 
 
public class Product 
{ 
    public int ProductID { get; set; } 
    public int CategoryID { get; set; } 
    public string ProductName { get; set; } 
    public int UnitsInStock { get; set; } 
    public string QuantityPerUnit { get; set; } 
    public bool Discontinued { get; set; } 
    public int voa_class { get; set; } 
 
    public int GetId() 
    { 
        return this.ProductID; 
    } 
} 
 
public class Category 
{ 
    public int CategoryID { get; set; } 
    public string CategoryName { get; set; } 
} 
 
private List<Product> GetProductLists() 
{ 
    var productList = new List<Product>() 
    { 
        new Product() { ProductID = 1, CategoryID = 1, ProductName = "test product", UnitsInStock = 3, QuantityPerUnit = "1", Discontinued = false, voa_class = 1 }, 
        new Product() { ProductID = 2, CategoryID = 1, ProductName = "Foo stuff", UnitsInStock = 50, QuantityPerUnit = "1", Discontinued = true, voa_class = 1 }, 
        new Product() { ProductID = 3, CategoryID = 2, ProductName = "More Stuff", UnitsInStock = 0, QuantityPerUnit = "1", Discontinued = true, voa_class = 1 } 
    }; 
    return productList; 
} 
 
private List<Category> GetCategoriesLists() 
{ 
    var categoriesList = new List<Category>() 
    { 
        new Category() { CategoryID = 1, CategoryName = "First" }, 
        new Category() { CategoryID = 2, CategoryName = "Second" } 
    }; 
    return categoriesList; 
} 

Important

To mock LINQ queries you first need to go to elevated mode by enabling TelerikJustMock from the menu. Learn how to do that in the How to Enable/Disable Telerik JustMock topic.

Asserting Custom Select Query

In the following example, we mock simple.Products to return a custom collection. After that, a LINQ query is executed against the collection to obtain a specifically desired value:

[TestMethod] 
public void ShouldAssertCustomSelect() 
{ 
    var simple = new SimpleData(); 
    Mock.Arrange(() => simple.Products).ReturnsCollection(GetProductLists()); 
 
    var expected = (from p in simple.Products 
        where p.UnitsInStock == 50 
        select p.ProductID).SingleOrDefault(); 
 
    Assert.AreEqual(expected, 2); 
} 
As simple.Products will return the collection defined by GetProductLists, the Product with UnitsInStock property set to 50 has the ProductID set to 2, and therefore the assertion will pass.

Asserting Projection

Let's extend the previous example. Here, in our LINQ query, we don't get directly the values we need, but construct a new object of type Product and verify the ProductID property.

[TestMethod] 
public void ShouldAssertProjectionWhenCombinedWithWhere() 
{ 
    var simple = new SimpleData(); 
    Mock.Arrange(() => simple.Products).ReturnsCollection(GetProductLists()); 
 
    var expected = (from p in simple.Products 
        where p.UnitsInStock == 50 
        select new { p.ProductID, p.ProductName }).SingleOrDefault(); 
 
    Assert.AreEqual(expected.ProductID, 2); 
} 

There is only one Product in the collection returned from GetProductLists() with UnitsInStock = 50 and its ProductID property yields 2.

Asserting Queries with Join Operator

Furthermore, you can use Join operations to create associations between sequences that are not explicitly modeled in the data sources. For example, you can perform a join to find the CategoryName of each product.

[TestMethod] 
public void ShouldAssertUsingJoinClause() 
{ 
    var simple = new SimpleData(); 
    Mock.Arrange(() => simple.Products).ReturnsCollection(GetProductLists()); 
    Mock.Arrange(() => simple.Categories).ReturnsCollection(GetCategoriesLists()); 
 
    var query = from product in simple.Products 
        join category in simple.Categories on product.CategoryID equals category.CategoryID  
        select category.CategoryName; 
 
    Assert.AreEqual(3, query.Count()); 
} 

Asserting Enumerable Source

With JustMock, you can also mock an enumerable source. Let's add the following method and a class:

public class MyDataContext : DataContext 
{ 
    public MyDataContext() : base(string.Empty) 
    { 
 
    } 
 
    public Table<Product> Products 
    { 
        get 
        { 
            return this.GetTable<Product>(); 
        } 
    } 
} 
 
private IQueryable<Product> GetFakeProducts() 
{ 
    List<Product> productList = GetProductLists(); 
 
    return productList.AsQueryable(); 
} 

We arrange dataContext.Products to return the collection defined in the GetFakeProducts method. Yet it implements IQueryable interface, we are allowed to use it in our assertion. Here we verify it contains 3 elements.

IList<Product> products; 
 
var dataContext = new MyDataContext(); 
 
Mock.Arrange(() => dataContext.Products).ReturnsCollection(GetFakeProducts()); 
 
products = dataContext.Products.ToList<Product>(); 
 
Assert.AreEqual(3, products.Count()); 

Asserting When Conditional Expression Is Passed in as a Parameter

You can also mock parameters when using the LINQ expressions. Let's walk through an example demonstrating how to mock the behavior of the == expression:

var simple = new SimpleData(); 
int targetProductId = 2; 
int expectedId = 10; 
 
Mock.Arrange( () => simple.Products ).ReturnsCollection( GetProductLists() ); 
Mock.Arrange( () => simple.Products.Where( x => x.ProductID == targetProductId ).First().GetId() ).Returns( expectedId ).MustBeCalled(); 
 
Product actual = simple.GetProduct( targetProductId ); 
 
Assert.AreEqual( expectedId, actual.GetId() ); 

In this example, we first define that the product collection must be a specific list of products. We then use LINQ to select a specific instance from the simple.Products collection. For that instance, we want to mock the call to the GetId() method in order to return a different id. Finally, we retrieve the target product and verify that the returned id and the expected id are the same.

In this article