Unit testing for adding record in DB - entity-framework

I am using unit testing first time.
I have created the class 'CAR' using entity framework.
I have following code in my project
namespace EntityFrameworkExample
{
class Program
{
static void Main(string[] args)
{
public static void AddCar()
{
SampleDBEntities db = new SampleDBEntities();
Car car = new Car();
car.Brand = "Ford";
car.Model = "Mastang";
db.Cars.AddObject(car);
db.SaveChanges();
Console.WriteLine("Record Saved");
Console.ReadLine();
}
}
}
}
Now I want to perform unit testing on this method.
I have added unit test project as well added ref of above project to it...
but I am confused abt how to call it ?
I have writen below code
namespace UnitTest
{
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestClass]
public class UnitTest1
{
[TestMethod]
public void AddCar()
{
SampleDBEntities e = new SampleDBEntities();
//what to do next ? ////////////////////////////////
}
}
}
I am confused abt next step what should I write ?

You should put the AddCar-method outside the Main-method to be able to call it. I would make a new class for the Car-functionality, outside of the Program class. Then you can call that class without having to interact with the program in your test.
For unit testing, do "Arrange", "Act", "Assert" inside your test method.
Arrange:
var cars = new Cars();
Act:
cars.AddCar("Ford", "Mustang");
Assert:
//check that car is in the database
var myCar = cars.GetCar("Ford", "Mustang");
Assert.IsNotNull(myCar);
To be able to test it, you should wipe the database before each test run.
edit for clarification:
namespace EntityFrameworkExample
{
class Program
{
static void Main(string[] args)
{
var cars = new Cars();
cars.AddCar("Ford", "Mustang");
}
}
public class Cars
{
public static void AddCar(string brand, string model)
{
SampleDBEntities db = new SampleDBEntities();
Car car = new Car();
car.Brand = brand;
car.Model = model;
db.Cars.AddObject(car);
db.SaveChanges();
Console.WriteLine("Record Saved");
Console.ReadLine();
}
public static Car GetCar(brand, model)
{
using(var db = new SampleDBEntities())
{
var car = from car in db.Cars
where car.Brand == brand
&& car.Model == model
select car;
return car.FirstOrDefault();
}
}
}
}

Related

Why does my ArrayList of objects print out one variable stored inside the object, but not the other

HandDrawn class extends the super-class Car, as you can see. The problem is it doesn't print out the the String name when i try to print the ArrayList that stores the objects. Btw, the ArrayList stores objects of the class Car.
Calm down, if i did something that offends your little feelings with this question, dont down vote... tell me what's up so i know in the future.
public class HandDrawn extends Card {
private boolean niceDrawing;
public HandDrawn(String name, boolean niceDrawing) {
super(name);
this.niceDrawing = niceDrawing;
}
#Override
public String toString() {
return "HandDrawn{" +
"niceDrawing=" + niceDrawing +
'}';
}
public void setNiceDrawing() {
this.niceDrawing = niceDrawing;
}
public boolean getNiceDrawing(boolean niceDrawing) {
return this.niceDrawing;
}
}
public class Main {
static ArrayList<Card> cards = new ArrayList<>();
public static void main(String[] args) {
cards.add(new HandDrawn("Anna", true));
cards.add(new HandDrawn("Kalle", false));
Main myApp = new Main();
myApp.cardList(cards);
}
public void cardList(ArrayList<Card> e) {
for (int i = 0; i <e.size(); i++) {
System.out.println(e.get(i));
}
}
}
This is the Main class and the HandDrawn class
Again, I don't know what is in your super class "Card" but maybe this will help:
In your HandDrawn.java file:
public class HandDrawn extends Card {
private boolean niceDrawing;
public HandDrawn(String name, boolean niceDrawing) {
super(name);
this.niceDrawing = niceDrawing;
}
#Override
public String toString() {
return "HandDrawn{" + "niceDrawing=" + this.niceDrawing + "}";
}
// Notice I have modified the parameters of your getters
// and setters because it looked as if you had swapped them:
public void setNiceDrawing(boolean niceDrawing) {
this.niceDrawing = niceDrawing;
}
public boolean getNiceDrawing() {
return this.niceDrawing;
}
}
In your Main.java file:
public class Main {
static ArrayList<Card> cards = new ArrayList();
public static void main(String[] args) {
// This is the entry point of your program... execution begins here.
cards.add(new HandDrawn("Anna", true));
cards.add(new HandDrawn("Kalle", false));
cardList(cards);
}
// The following two lines are out of place and should not be in class definition:
// Main myApp = new Main();
// myApp.cardList(cards);
// I added static keyword so that it could be used in call above
public static void cardList(ArrayList<Card> e) {
for (int i = 0; i < e.size(); i++) {
System.out.println(e.get(i));
}
}
If you are wanting to use the "Main" class as a piece in another part of your code then probably that means that execution starts somewhere else and never hits the "main" method. If that is the case you will need to call it explicitly (example: Main.main(null);) or reorganize your code to do it in a constructor for the "Main" class. Then your Main myApp = new Main(); and myApp.cardList(cards); lines would make sense in that context and the cardList method would need to be a non-static member method as you had originally written.
EDIT:
I think I misunderstood your formatting... Your code should work as follows:
In your Main.java file:
public class Main {
static ArrayList<Card> cards = new ArrayList();
public static void main(String[] args) {
// This is the entry point of your program... execution begins here.
cards.add(new HandDrawn("Anna", true));
cards.add(new HandDrawn("Kalle", false));
Main myApp = new Main();
myApp.cardList(cards);
}
public void cardList(ArrayList<Card> e) {
for (int i = 0; i < e.size(); i++) {
System.out.println(e.get(i));
}
}
What were you expecting to see? Again I cannot test your code because I don't have "Card" class but when I use the "HandDrawn" class in place of "Card" (without extending "Card") it works as I would expect and prints:
HandDrawn{niceDrawing=true}
HandDrawn{niceDrawing=false}

Entity Framework Core 1.1 In Memory Database fails adding new entities

I am using the following code in a unit test for the test setup:
var simpleEntity = new SimpleEntity();
var complexEntity = new ComplexEntity
{
JoinEntity1List = new List<JoinEntity1>
{
new JoinEntity1
{
JoinEntity2List = new List<JoinEntity2>
{
new JoinEntity2
{
SimpleEntity = simpleEntity
}
}
}
}
};
var anotherEntity = new AnotherEntity
{
ComplexEntity = complexEntity1
};
using (var context = databaseFixture.GetContext())
{
context.Add(anotherEntity);
await context.SaveChangesAsync();
}
When SaveChangesAsync is reached EF throws an ArgumentException with the following message:
An item with the same key has already been added. Key: 1
I'm using a fixture as well for the unit test class which populates the database with objects of the same types, though for this test I want this particular setup so I want to add these new entities to the in memory database. I've tried adding the entities on the DbSet (not the DbContext) and adding all three entities separatly to no avail. I can however add "simpleEntity" separately (because it is not added in the fixture) but EF complains as soon as I try to add "complexEntity" or "anotherEntity".
It seems like EF in memory database cannot handle several Add's over different instances of the context. Is there any workaround for this or am I doing something wrong in my setup?
The databaseFixture in this case is an instance of this class:
namespace Test.Shared.Fixture
{
using Data.Access;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
public class InMemoryDatabaseFixture : IDatabaseFixture
{
private readonly DbContextOptions<MyContext> contextOptions;
public InMemoryDatabaseFixture()
{
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
var builder = new DbContextOptionsBuilder<MyContext>();
builder.UseInMemoryDatabase()
.UseInternalServiceProvider(serviceProvider);
contextOptions = builder.Options;
}
public MyContext GetContext()
{
return new MyContext(contextOptions);
}
}
}
You can solve this problem by using Collection Fixtures so you can share this fixture across several test classes. This way you don't build you context several times and thus you won't get this exception:
Some information about collection Fixture
My own example:
[CollectionDefinition("Database collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{ }
[Collection("Database collection")]
public class GetCitiesCmdHandlerTests : IClassFixture<MapperFixture>
{
private readonly TecCoreDbContext _context;
private readonly IMapper _mapper;
public GetCitiesCmdHandlerTests(DatabaseFixture dbFixture, MapperFixture mapFixture)
{
_context = dbFixture.Context;
_mapper = mapFixture.Mapper;
}
[Theory]
[MemberData(nameof(HandleTestData))]
public async void Handle_ShouldReturnCountries_AccordingToRequest(
GetCitiesCommand command,
int expectedCount)
{
(...)
}
public static readonly IEnumerable<object[]> HandleTestData
= new List<object[]>
{
(...)
};
}
}
Good luck,
Seb

Autofac: cannot resolve dependency using factory after ContainerBuilder.Update()

My problem is that I want to use Func<> factory to resolve dependency. And in if I use ContainerBuilder Update() (I need it for mocking some services in integration tests), this factories still resolve outdated instances.
I created simple scenario to reproduce the problem:
class Program
{
static void Main(string[] args)
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Test>().As<ITest>();
containerBuilder.RegisterType<Test1Factory>().As<ITestFactory>();
containerBuilder.RegisterType<TestConsumer>().AsSelf();
var container = containerBuilder.Build();
var tc1 = container.Resolve<TestConsumer>();
var cbupdater = new ContainerBuilder();
cbupdater.RegisterType<Test2>().As<ITest>();
cbupdater.RegisterType<Test2Factory>().As<ITestFactory>();
cbupdater.Update(container);
var tc2 = container.Resolve<TestConsumer>();
Console.ReadLine();
}
}
public interface ITest
{
int Id { get; set; }
}
public class Test : ITest
{
public Test()
{
Id = 1;
}
public int Id { get; set; }
}
public class Test2 : ITest
{
public Test2()
{
Id = 2;
}
public int Id { get; set; }
}
public interface ITestFactory
{
ITest Create();
}
public class Test1Factory : ITestFactory
{
public ITest Create()
{
return new Test();
}
}
public class Test2Factory : ITestFactory
{
public ITest Create()
{
return new Test2();
}
}
public class TestConsumer
{
public TestConsumer(Func<ITest> testFactory, ITest test, ITestFactory customFactory)
{
Console.WriteLine("factory: " + testFactory().Id);
Console.WriteLine("direct: " + test.Id);
Console.WriteLine("MyCustomFactory: " + customFactory.Create().Id);
Console.WriteLine("*************");
Console.WriteLine();
}
}
The output is:
factory: 1 direct: 1 MyCustomFactory: 1
factory: 1 direct: 2 MyCustomFactory: 2
Notice "factory: 1" in both cases.
Am I missing something or I have to create my cusom factory in this scenario?
P.S.
Autofac 3.5.2 or 4.0 beta 8-157
.net 4.5.1
That's by design unfortunately, the reasons, I don't know. Looking at the Autofac code gives you a better insight on how they register items with the same interface definition, in short, all registrations are maintained but the last registration wins (ref). Wait...that's not all, weirdly, for Fun<...>, you actually get them in order. You can easily test by changing the constructor of the TestConsumer class to:
public TestConsumer(Func<ITest> testFactory, IEnumerable<Func<ITest>> testFactories, IEnumerable<ITest> tests, ITest test, ITestFactory customFactory)
{
// ...
}
Note that you get all the Funcs and the ITest registration. You are simply lucky that resolving ITest directly resolves to Test2.
Now, having said all of the above, there is a way described here. You have to create a container without the registration you want to override, therefore:
/// <summary>
/// This has not been tested with all your requirements
/// </summary>
private static IContainer RemoveOldComponents(IContainer container)
{
var builder = new ContainerBuilder();
var components = container.ComponentRegistry.Registrations
.Where(cr => cr.Activator.LimitType != typeof(LifetimeScope))
.Where(cr => cr.Activator.LimitType != typeof(Func<ITest>));
foreach (var c in components)
{
builder.RegisterComponent(c);
}
foreach (var source in container.ComponentRegistry.Sources)
{
builder.RegisterSource(source);
}
return builder.Build();
}
And you can simply change your main method to the following:
static void Main(string[] args)
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<Test>().As<ITest>();
containerBuilder.RegisterType<Test1Factory>().As<ITestFactory>();
containerBuilder.RegisterType<TestConsumer>().AsSelf();
var container = containerBuilder.Build();
var tc1 = container.Resolve<TestConsumer>();
container = RemoveOldComponents(container);
var cbupdater = new ContainerBuilder();
cbupdater.RegisterType<Test2>().As<ITest>();
cbupdater.RegisterType<Test2Factory>().As<ITestFactory>();
cbupdater.Update(container);
var tc2 = container.Resolve<TestConsumer>();
Console.ReadLine();
}
PS: Wouldn't it be great to have a method which does the exact opposite of PreserveExistingDefaults()

How to UnitTest a Service with EntityFramework, Repository and Moq?

Im working on a C# Project that uses Entity Framework, Repository-Pattern, UnitOfWork-Pattern and Moq.
I´m new to EF and Unit Tests with Moq and got the following problem:
I get null pointers, when i try to test the methods from the service class...and it seems as if the context can´t get instantiated. Can anyone point my mistake out or provide me with a link?
Example:
portionService.cs
/// <summary>
/// The PortionService class represents a service for the Portion model.
/// </summary>
public class PortionService : Service, IPortionService
{
/// <summary>
/// In this constructor the base constructor of the Service class is called.
/// </summary>
/// <param name="context">Represents a context of the data access layer.</param>
public PortionService(IDALContext context) : base(context) { }
public void Add(Portion portion)
{
context.Portion.Create(portion);
context.SaveChanges();
}
public Portion GetPortionByName(string name)
{
return context.Portion.GetAll().Where(p => p.Name.ToUpper() == name.ToUpper()).LastOrDefault();
}
portionServiceTests.cs
// TestClass for PortionService-Tests
[TestClass]
public class PortionServiceTests
{
private PortionService _portionService;
// define the mock object
private Mock<IPortionService> _portionServiceMock;
[TestInitialize]
public void Init()
{
_portionService = new PortionService(new DALContext());
// create the mock object
_portionServiceMock = new Mock<IPortionService>();
}[TestMethod]
public void EnteringPortionNameReturnsThePortion()
{
//arrange
// arrange data
Portion portion = new Portion { PortionID = 12, Name = "testPortion" };
//arrange expectations
_portionServiceMock.Setup(service => service.GetPortionByName("testPortion")).Returns(portion).Verifiable();
//act
var result = _portionService.GetPortionByName("testPortion");
//verify
Assert.AreEqual(portion, result.Name);
}
DALContext.cs
public class DALContext : IDALContext, IDisposable
{
/// <summary>
/// The _context property represents the context to the current Database.
/// </summary>
private DatabaseContext _context;
private Repository<Portion> _portionRepository;
...
/// <summary>
/// In this constructor the single instance of the DataBaseContext gets instantiated.
/// </summary>
public DALContext()
{
_context = new DatabaseContext();
}
You are trying to verify the mock result to an actual data in the database, that's why it fails. Your unit test should test the service, and that the service calls the context, not the mock of the service itself.
The following example uses FakeDbSet approach from Rowan Miller's article.
using System.Data.Entity;
using System.Linq;
using Moq;
using NUnit.Framework;
using SharpTestsEx;
namespace StackOverflowExample.EntityFramework
{
public class DataEntity
{
public int Id { get; set; }
public string Data { get; set; }
}
public interface IContext
{
IDbSet<DataEntity> DataEntities { get; }
}
public class DataService
{
private IContext _db;
public DataService(IContext context)
{
_db = context;
}
public DataEntity GetDataById(int id)
{
return _db.DataEntities.First(d => d.Id == id);
}
}
[TestFixture]
public class DataServiceTests
{
[Test]
public void GetDataByIdTest()
{
//arrange
var datas = new FakeDbSet<DataEntity>
{
new DataEntity {Id = 1, Data = "one"},
new DataEntity {Id = 2, Data = "two"}
};
var context = new Mock<IContext>();
context.SetupGet(c => c.DataEntities).Returns(datas);
var service = new DataService(context.Object);
//act
var result = service.GetDataById(2);
//assert
result.Satisfy(r =>
r.Id == 2
&& r.Data == "two");
}
}
}
it's actually not easy to unit test EF based application. I would recommend using a library like effort to mock the entity framework.

how to update an entity in Entity Framework 4 .NET

my code is something like this:
public class Program
{
[STAThread]
static void main()
{
DataAccessClass dal = new DataAccessClass();
List<Person> list = dal.GetPersons();
Person p = list[0];
p.LastName = "Changed!";
dal.Update(p);
}
}
public class DataAccessClass
{
public static List<Person> GetPersons()
{
MyDBEntities context = new MyDBEntities();
return context.Persons.ToList();
}
public void Update(Person p)
{
// what sould be written here?
}
}
now please tell me what should i write in the Update() method?
everything i write , encounters various exceptions.
(please pay attention that the data loaded is tracked , connected or something like that)
The problem is that your Person entities are still attached to context created in GetPersons. If you want to work with attached entities you have to use same context instance in both select and update operations. You have two choices to solve your problem.
1) Correctly handled attached entities
public class Program
{
[STAThread]
static void main()
{
using (DataAccessClass dal = new DataAccessClass())
{
List<Person> list = dal.GetPersons();
Person p = list[0];
p.LastName = "Changed!";
dal.Save();
}
}
}
public class DataAccessClass : IDisposable
{
private MyDBEntities _context = new MyDBEntities();
public List<Person> GetPersons()
{
return _context.Persons.ToList();
}
public void Save()
{
// Context tracks changes on your entities. You don't have to do anything. Simply call
// SaveChanges and all changes in all loaded entities will be done in DB.
_context.SaveChanges();
}
public void Dispose()
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
2) Don't use attached entities
public class Program
{
[STAThread]
static void main()
{
DataAccessClass dal = new DataAccessClass())
List<Person> list = DataAccessClass.GetPersons();
Person p = list[0];
p.LastName = "Changed!";
dal.Update(p);
}
}
public class DataAccessClass
{
public static List<Person> GetPersons()
{
// Closing context will detach entities
using (MyDBEntities context = new MyDBEntities())
{
return context.Persons.ToList();
}
}
public void Update(Person p)
{
using (MyDBEntities context = new MyDBEntities())
{
context.Persons.Attach(p);
// Detached entities don't track changes so after attaching you have to say
// what changes have been done
context.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Modified);
context.SaveChanges();
}
}
}
Taken from Employee Info Starter Kit, you can consider the code snippet as below:
public void UpdateEmployee(Employee updatedEmployee)
{
//attaching and making ready for parsistance
if (updatedEmployee.EntityState == EntityState.Detached)
_DatabaseContext.Employees.Attach(updatedEmployee);
_DatabaseContext.ObjectStateManager.ChangeObjectState(updatedEmployee, System.Data.EntityState.Modified);
_DatabaseContext.SaveChanges();
}
does not work when you have a property on entity which is a ConcurrencyToken.
At least for me. Because you then get a OptimisticConcurrencyException.
What i do (and i think this is not an optimum solution),
facts:
- I use a new context because of n-tier. So, the previous/original entity with its values are not known. Either you supplies the context with original and old (bah) or like me load original first prior to update:
T originalItem = sessionManager.Set().Single(x => x.ID == changedEntity.ID);
if(changedEntity.lastChangedDate != originalItem.lastChangedDate)
throw new OptimisticConcurrencyException(String.Format("Trying to update entity with lastChangedDate {0} using lastChangedDate {1}!", originalItem.lastChangedDate, changedEntity.lastChangedDate));
ObjectStateEntry state = sessionManager.ObjectStateManager.GetObjectStateEntry(originalItem);
state.ApplyCurrentValues(changedEntity);
state.ChangeState(System.Data.EntityState.Modified);
sessionManager.SaveChanges();
If you know something better, please let me know.
Atam