Lightly touch EntityFramework article (#129)
This commit is contained in:
Родитель
1599f26cf2
Коммит
3a2fda3033
|
@ -17,36 +17,35 @@ __Telerik® JustMock__ allows you to perform unit testing in conjunctions with t
|
|||
|
||||
With __Microsoft Entity Framework__, you develop data access applications by using a conceptual application model instead of a relational storage schema.
|
||||
|
||||
__JustMock__ supports the Microsoft Entity Framework thanks to the [Telerik.JustMock.EntityFramework](https://github.com/tailsu/Telerik.JustMock.EntityFramework) package. This package allows you to easily create in-memory mocks of the DbSet and DbContext types. It also provides additional mocking amenities for JustMock.
|
||||
__JustMock__ supports both EntityFramework and EntityFrameworkCore thanks to the extension packages respectively [Telerik.JustMock.EntityFramework](https://github.com/telerik/Telerik.JustMock.EntityFramework) and [Telerik.JustMock.EntityFrameworkCore](https://github.com/telerik/Telerik.JustMock.EntityFrameworkCore). The packages allows you to easily create in-memory mocks of the DbSet and DbContext types. It also provides additional mocking amenities for JustMock.
|
||||
|
||||
In this topic, we will cover some scenarios in unit testing Microsoft Entity Framework. In the examples below, we use the `DbContext` class along with the following methods:
|
||||
In this topic, we will cover some common scenarios in the EntityFramework unit testing. In the examples below, we use the `DbContext` class along with the following methods:
|
||||
|
||||
#### __[C#]__
|
||||
#### __[C#]__
|
||||
|
||||
{{region EntityFramework#Samples}}
|
||||
public class NerdDinners : DbContext
|
||||
{
|
||||
public DbSet<Dinner> Dinners { get; set; }
|
||||
public DbSet<RSVP> RSVPs { get; set; }
|
||||
}
|
||||
|
||||
public class Dinner
|
||||
{
|
||||
public int DinnerID { get; set; }
|
||||
public string Title { get; set; }
|
||||
public DateTime EventDate { get; set; }
|
||||
public string Address { get; set; }
|
||||
public string HostedBy { get; set; }
|
||||
}
|
||||
|
||||
public class RSVP
|
||||
{
|
||||
public int RSVPID { get; set; }
|
||||
public int DinnerID { get; set; }
|
||||
public string AtendeeEmail { get; set; }
|
||||
}
|
||||
|
||||
{{endregion}}
|
||||
{{region EntityFramework#Samples}}
|
||||
public class NerdDinners : DbContext
|
||||
{
|
||||
public DbSet<Dinner> Dinners { get; set; }
|
||||
public DbSet<RSVP> RSVPs { get; set; }
|
||||
}
|
||||
|
||||
public class Dinner
|
||||
{
|
||||
public int DinnerID { get; set; }
|
||||
public string Title { get; set; }
|
||||
public DateTime EventDate { get; set; }
|
||||
public string Address { get; set; }
|
||||
public string HostedBy { get; set; }
|
||||
}
|
||||
|
||||
public class RSVP
|
||||
{
|
||||
public int RSVPID { get; set; }
|
||||
public int DinnerID { get; set; }
|
||||
public string AtendeeEmail { get; set; }
|
||||
}
|
||||
{{endregion}}
|
||||
|
||||
|
||||
## Returning A Fake Collection
|
||||
|
@ -55,19 +54,19 @@ The following steps demonstrate how to return a fake collection:
|
|||
|
||||
1. Create a method that returns a fake collection of `Dinner`s. For this example, we use the code below:
|
||||
|
||||
#### __[C#]__
|
||||
#### __[C#]__
|
||||
|
||||
{{region EntityFramework#FakeDinnersReturn}}
|
||||
{{region EntityFramework#FakeDinnersReturn}}
|
||||
public IList<Dinner> FakeDinners()
|
||||
{
|
||||
List<Dinner> fakeDin = new List<Dinner>
|
||||
{
|
||||
new Dinner { Address = "1 Microsoft way", DinnerID = 1, EventDate =DateTime.Now, HostedBy = "Telerik" , Title = "Telerik Dinner"}
|
||||
};
|
||||
|
||||
return fakeDin;
|
||||
}
|
||||
{{endregion}}
|
||||
{
|
||||
List<Dinner> fakeDin = new List<Dinner>
|
||||
{
|
||||
new Dinner { Address = "1 Microsoft way", DinnerID = 1, EventDate =DateTime.Now, HostedBy = "Telerik" , Title = "Telerik Dinner"}
|
||||
};
|
||||
|
||||
return fakeDin;
|
||||
}
|
||||
{{endregion}}
|
||||
|
||||
1. Create a new instance of the `NerdDinners` class.
|
||||
|
||||
|
@ -81,101 +80,100 @@ The following steps demonstrate how to return a fake collection:
|
|||
>
|
||||
> Note that when you use `ReturnsCollection()` you must be using the `Telerik.JustMock.Helpers;`.
|
||||
|
||||
#### __[C#]__
|
||||
#### __[C#]__
|
||||
|
||||
{{region EntityFramework#MockingCollectionReturn}}
|
||||
[TestMethod]
|
||||
public void ShouldReturnFakeCollectionWhenExpected()
|
||||
{
|
||||
NerdDinners nerdDinners = new NerdDinners();
|
||||
|
||||
// Arrange
|
||||
Mock.Arrange(() => nerdDinners.Dinners).ReturnsCollection(FakeDinners());
|
||||
|
||||
// Act
|
||||
var query = from d in nerdDinners.Dinners
|
||||
where d.DinnerID == 1
|
||||
select d;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, query.Count());
|
||||
Assert.AreEqual(1, query.First().DinnerID);
|
||||
|
||||
}
|
||||
{{endregion}}
|
||||
{{region EntityFramework#MockingCollectionReturn}}
|
||||
[TestMethod]
|
||||
public void ShouldReturnFakeCollectionWhenExpected()
|
||||
{
|
||||
NerdDinners nerdDinners = new NerdDinners();
|
||||
|
||||
// Arrange
|
||||
Mock.Arrange(() => nerdDinners.Dinners).ReturnsCollection(FakeDinners());
|
||||
|
||||
// Act
|
||||
var query = from d in nerdDinners.Dinners
|
||||
where d.DinnerID == 1
|
||||
select d;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, query.Count());
|
||||
Assert.AreEqual(1, query.First().DinnerID);
|
||||
}
|
||||
{{endregion}}
|
||||
|
||||
## Returning A Fake Collection with Future Mocking
|
||||
|
||||
In this example we will return the same fake collection.
|
||||
|
||||
#### __[C#]__
|
||||
#### __[C#]__
|
||||
|
||||
{{region EntityFramework#FakeDinnersReturn}}
|
||||
{{region EntityFramework#FakeDinnersReturn}}
|
||||
public IList<Dinner> FakeDinners()
|
||||
{
|
||||
List<Dinner> fakeDin = new List<Dinner>
|
||||
{
|
||||
new Dinner { Address = "1 Microsoft way", DinnerID = 1, EventDate =DateTime.Now, HostedBy = "Telerik" , Title = "Telerik Dinner"}
|
||||
};
|
||||
|
||||
return fakeDin;
|
||||
}
|
||||
{{endregion}}
|
||||
{
|
||||
List<Dinner> fakeDin = new List<Dinner>
|
||||
{
|
||||
new Dinner { Address = "1 Microsoft way", DinnerID = 1, EventDate =DateTime.Now, HostedBy = "Telerik" , Title = "Telerik Dinner"}
|
||||
};
|
||||
|
||||
return fakeDin;
|
||||
}
|
||||
{{endregion}}
|
||||
|
||||
To assure that the instance does not matter during the __Act__ phase we will make a repository class:
|
||||
|
||||
#### __[C#]__
|
||||
#### __[C#]__
|
||||
|
||||
{{region EntityFramework#DinnersRepository}}
|
||||
public class DinnerRepository
|
||||
{
|
||||
public Dinner GetById(int dinnerId)
|
||||
{
|
||||
NerdDinners nerdDinners = new NerdDinners();
|
||||
var query = from d in nerdDinners.Dinners
|
||||
where d.DinnerID == 1
|
||||
select d;
|
||||
|
||||
return query.First();
|
||||
}
|
||||
}
|
||||
{{endregion}}
|
||||
{{region EntityFramework#DinnersRepository}}
|
||||
public class DinnerRepository
|
||||
{
|
||||
public Dinner GetById(int dinnerId)
|
||||
{
|
||||
NerdDinners nerdDinners = new NerdDinners();
|
||||
var query = from d in nerdDinners.Dinners
|
||||
where d.DinnerID == 1
|
||||
select d;
|
||||
|
||||
return query.First();
|
||||
}
|
||||
}
|
||||
{{endregion}}
|
||||
|
||||
As you see, in the test below we are acting with a `new DinnerRepository()`, but still we are meeting the expectations and the test passes. This behavior is known and expected in [Future Mocking]({%slug justmock/advanced-usage/future-mocking%}).
|
||||
|
||||
> Note that when you use `ReturnsCollection()` you must be using the `Telerik.JustMock.Helpers;` namespace.
|
||||
|
||||
#### __[C#]__
|
||||
#### __[C#]__
|
||||
|
||||
{{region EntityFramework#FutureMockingCollectionReturn}}
|
||||
[TestMethod]
|
||||
public void ShouldReturnFakeCollectionForFutureInstance()
|
||||
{
|
||||
NerdDinners nerdDinners = new NerdDinners();
|
||||
|
||||
Mock.Arrange(() => nerdDinners.Dinners).IgnoreInstance().ReturnsCollection(FakeDinners());
|
||||
|
||||
Assert.AreEqual(1, new DinnerRepository().GetById(1).DinnerID);
|
||||
}
|
||||
{{endregion}}
|
||||
{{region EntityFramework#FutureMockingCollectionReturn}}
|
||||
[TestMethod]
|
||||
public void ShouldReturnFakeCollectionForFutureInstance()
|
||||
{
|
||||
NerdDinners nerdDinners = new NerdDinners();
|
||||
|
||||
Mock.Arrange(() => nerdDinners.Dinners).IgnoreInstance().ReturnsCollection(FakeDinners());
|
||||
|
||||
Assert.AreEqual(1, new DinnerRepository().GetById(1).DinnerID);
|
||||
}
|
||||
{{endregion}}
|
||||
|
||||
## Faking the Add of an Entity
|
||||
|
||||
In the next example we will __Arrange__ the calling of the `Add()` method to actually add an item to a previously created local collection.
|
||||
|
||||
#### __[C#]__
|
||||
|
||||
{{region EntityFramework#FakingAdd}}
|
||||
[TestMethod]
|
||||
public void ShouldReturnFakeCollectionForFutureInstance()
|
||||
{
|
||||
NerdDinners nerdDinners = new NerdDinners();
|
||||
|
||||
Mock.Arrange(() => nerdDinners.Dinners).IgnoreInstance().ReturnsCollection(FakeDinners());
|
||||
|
||||
Assert.AreEqual(1, new DinnerRepository().GetById(1).DinnerID);
|
||||
}
|
||||
{{endregion}}
|
||||
#### __[C#]__
|
||||
|
||||
{{region EntityFramework#FakingAdd}}
|
||||
[TestMethod]
|
||||
public void ShouldReturnFakeCollectionForFutureInstance()
|
||||
{
|
||||
NerdDinners nerdDinners = new NerdDinners();
|
||||
|
||||
Mock.Arrange(() => nerdDinners.Dinners).IgnoreInstance().ReturnsCollection(FakeDinners());
|
||||
|
||||
Assert.AreEqual(1, new DinnerRepository().GetById(1).DinnerID);
|
||||
}
|
||||
{{endregion}}
|
||||
|
||||
Here are the steps:
|
||||
|
||||
|
@ -185,5 +183,5 @@ Here are the steps:
|
|||
1. Arrange that the `SaveChanges()` method is doing nothing.
|
||||
1. Act by calling `Add(dinner)` and `SaveChanges()`.
|
||||
1. Verify that:
|
||||
* the collection has exactly *one* item
|
||||
* this item is exactly the object from *step 2.*
|
||||
* the collection has exactly *one* item
|
||||
* this item is exactly the object from *step 2.*
|
||||
|
|
Загрузка…
Ссылка в новой задаче