Difference between a Repository Implementation using ObjectContext vs DbContext on EF 4.1 - repository-pattern

What could be the better implementation for STE, I heard about that DbContext is the simplest way to implement a Repo with EF, personally I take advantage of the EntityState, but there is any member on ObjectContext that could deliver more functionallity for my CRUD operations using Repo? at today I'm using a GenericRepository like this one :
public class GenericRepository<TEntity> where TEntity : class
{
internal DbContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(DbContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
}
I forgot to mention that also I'm using Unity, so the calls to Repository are like this way :
[Dependency]
public IUnityContainer Container { get; set; }
public List<Case> GetAll()
{
using (var context = Container.Resolve<ClaimEntities>())
{
var qry = (from c in context.Cases
select c).ToList();
return qry;
}
}

Self tracking entities are feature of ObjectContext - they are not supported in DbContext. If you want STEs you need to swap to ObjectContext API and use STEs T4 template to generate entities instead of your current POCOs.

Related

Unable to resolve service for type 'Api.Repositories.UnitOfWork' while attempting to activate 'Api.ServicesBusiness.EquipoServices'

I want to make a webapi and I'm trying to do it through the services way, I have a repository generic and another 2 repository and a unit of work, apparently everything goes fine, but when I run and test the webapi from postman I got that error:
InvalidOperationException: Unable to resolve service for type 'Api.Repository.Repositories.UnitOfWork' while attempting to activate 'Api.ServicesBusiness.Implementacion.EquipoServices'.
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, bool throwIfCallSiteNotFound)
Here is the my dbcontect:
public class AppDbContext : DbContext
{
public AppDbContext()
{
}
public AppDbContext(DbContextOptions<AppDbContext> option) :base(option)
{
}
public DbSet<Equipo> Equipos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\Express;Database=SoftballLeague;Trusted_Connection=True");
}
}
}
Here is the interface of my generic repository:
public interface IGenericRepository<T> where T : class
{
Task<T> AddAsyn(T t);
Task<T> UpdateAsyn(T t, object key);
}
Here is the implementation of my generic repository:
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private readonly AppDbContext _context;
private readonly DbSet<T> _dbSet;
public GenericRepository(AppDbContext context)
{
_context = context;
_dbSet = _context.Set<T>();
}
public virtual async Task<T> AddAsyn(T t)
{
_dbSet.Add(t);
await _context.SaveChangesAsync();
return t;
}
public virtual async Task<T> UpdateAsyn(T t, object key)
{
if (t == null)
return null;
T exist = await _dbSet.FindAsync(key);
if (exist != null)
{
_context.Entry(exist).CurrentValues.SetValues(t);
await _context.SaveChangesAsync();
}
return exist;
}
}
Here is the interface of my equipo repository:
public interface IEquipoRepository:IGenericRepository<Team>
{
int GetAverageTeam(string name);
int GetTeamHit(string name);
}
Here is the implementation of my equipo repository:
public class EquipoRepository : GenericRepository<Team>, IEquipoRepository
{
private readonly AppDbContext dbContext;
public EquipoRepository(AppDbContext context) : base(context)
{
this.dbContext = context;
}
public int GetAverageTeam(string name)
{
int teamAverage = 0;
var resultAverage = this.dbContext.Equipos
//.SelectMany(bItem => bItem.)
.Where(equipo=>equipo.Nombre==name)
.SelectMany(equipo => equipo.jugadores)
.Average(jugador => jugador.Average);
if (resultAverage.HasValue)
teamAverage =Convert.ToInt32(Math.Round(resultAverage.Value));
return teamAverage;
}
public int GetTeamHit(string name)
{
int resultTotal = 0;
var result = this.dbContext.Equipos
//.SelectMany(bItem => bItem.)
.Where(equipo => equipo.Nombre == name)
.SelectMany(equipo => equipo.jugadores)
.Sum(jugador => jugador.Cant_Hits_Conectados);
if (result.HasValue)
resultTotal = result.Value;
return resultTotal;
}
}
Here is the interface of my unit of work:
public interface IUnitOfWork:IDisposable
{
Task Commit();
}
Here is the implementation of my unit of work:
public class UnitOfWork : IUnitOfWork
{
private readonly AppDbContext _DbContext;
private EquipoRepository equipoRepository ;
public UnitOfWork(AppDbContext dbContext)
{
this._DbContext = dbContext;
this.equipoRepository = new EquipoRepository(this._DbContext);
}
public EquipoRepository GetEquipoRepository{
get {
if(this.equipoRepository==null)
this.equipoRepository= new EquipoRepository(this._DbContext);
return this.equipoRepository;
}
}
public async Task Commit()
{
await this._DbContext.SaveChangesAsync();
}
public void Dispose()
{
this._DbContext.Dispose();
}
}
Here is the implementation of services interfaces IEquipoServices:
public interface IEquipoServices
{
ICollection<EstadisticaEquipoModel>AveragePorEquipo(string name);
int Total2bleConectados(string name);
}
Here is the implementation of services EquipoServices which is the one who throws the error:
public class EquipoServices : IEquipoServices
{
private readonly UnitOfWork unit;
public EquipoServices(UnitOfWork unitOfWorkFactory)
{
this.unit = unitOfWorkFactory;
}
public ICollection<EstadisticaEquipoModel> AveragePorEquipo(string name)
{
var equipoAverage= this.unit.GetEquipoRepository.GetAverageEquipo(name);
return equipoAverage;
}
public int AveragePorEquipo(string name)
{
var result = this.unit.GetEquipoRepository.GetEquipoTotal2bleConectados(name);
return result;
}
}
This is the controller, here I am just running the ListadoEquipos() method:
[Route("api/[controller]")]
public class EquipoController : ControllerBase
{
private readonly IEquipoServices equipoService;
private readonly IMapper _mapper;
public EquipoController(IEquipoServices eqService, IMapper mapper)
{
this.equipoService = eqService;
this._mapper = mapper;
}
[HttpGet("list")]
public IEnumerable<string> ListadoEquipos()
{
return new string[] { "value1", "value2" };
}
}
This is the configuration in the startup.cs file:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(options=>options.UseSqlServer(Configuration.GetConnectionString("ConnectionString")));
services.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
services.AddSingleton<IEquipoServices, EquipoServices>();
//services.AddScoped<IJu, JugadorService>();
services.AddAutoMapper(typeof(Startup));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
You registered IUnitOfWork, but you're injecting UnitOfWork. The service collection doesn't know how to inject UnitOfWork directly.
Long and short, inject IUnitOfWork instead:
private readonly IUnitOfWork unit;
public EquipoServices(IUnitOfWork unitOfWorkFactory)

Does the Repository connected to a Unit of Work need to be mocked for Unit Testing in ASP.NET Web API?

I have a Unit of Work pattern along with a Repo pattern to interact with the db layer (Entity Framework in this case) and then I have dependency injection going on in the controller's constructor. My question is, so I've mocked a IUnitOfWork which is what the controller interacts with, however, the Unit Of Work class actually accesses the repository so do I also have to mock a repository and if so, how would I implement this? I'm trying to complete a unit test of a basic Get controller method. I've read and watched several hours of video and articles and this is what I have so far:
class UrlControllerTests
{
[TestMethod]
public void ShouldReturnUrlList()
{
Mock<IUnitOfWork> fakeUnitOfWork = new Mock<IUnitOfWork>();
var urlController = new UrlController(fakeUnitOfWork.Object);
urlController.Get(5); //All this is just to see if we can get thru a test.
Assert.IsTrue(true);
}
IRepo
public interface IRepo<TEntity> where TEntity: class
{
TEntity Get(int id);
IEnumerable<TEntity> GetAll();
//Allows the running of lamba-style LINQ queries like the typical Entity Framework does:
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
void Add(TEntity entity);
void AddRange(IEnumerable<TEntity> entities);
void Remove(TEntity entity);
void RemoveRange(IEnumerable<TEntity> entities);
}
IUnitOfWork:
public interface IUnitOfWork :IDisposable {
IRepo<Url> Urls { get; }
int Complete();
}
UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
private readonly ApplicationDbContext _context;
public IRepo<Url> Urls { get; set; }
public UnitOfWork(ApplicationDbContext context)
{
_context = context;
Urls = new Repo<Url>(_context);
}
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
Repo:
public class Repo<TEntity> : IRepo<TEntity> where TEntity : class
{
protected readonly ApplicationDbContext _context;
public Repo(ApplicationDbContext context)
{
_context = context;
}
public TEntity Get(int id)
{
return _context.Set<TEntity>().Find(id);
}
//Repositories SHOULD NOT return IQueryable because otherwise other resources may
//Try to build queries
public IEnumerable<TEntity> GetAll()
{
return _context.Set<TEntity>().ToList();
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return _context.Set<TEntity>().Where(predicate);
}
public void Add(TEntity entity)
{
_context.Set<TEntity>().Add(entity);
}
public void AddRange(IEnumerable<TEntity> entities)
{
_context.Set<TEntity>().AddRange(entities);
}
public void Remove(TEntity entity)
{
_context.Set<TEntity>().Remove(entity);
}
public void RemoveRange(IEnumerable<TEntity> entities)
{
_context.Set<TEntity>().RemoveRange(entities);
}
}
}
I am using moq.
EDIT: What I'm trying to test:
public IHttpActionResult Get(int id)
{
var url = _unitOfWork.Urls.Get(id);
if (url == null)
{
NotFound();
}
return Ok(url);
}
The Target Method under test is dependent on the IUnitOfWork and IRepo<Url>. When creating unit tests you would normally mock the dependencies of the system under test so that it can be tested in isolation without having dependencies calling actual implementations (Integration Tests).
[TestClass]
public class UrlControllerTests {
[TestMethod]
public void Get_With_Valid_Id_Should_Return_Url() {
//Arrange
var testId = 5;
var expected = new Url { Id = testId };
var mockRepo = new Mock<IRepo<Url>>();
mockRepo.Setup(m => m.Get(testId)).Returns(expected);
var mockUnitOfWork = new Mock<IUnitOfWork>();
mockUnitOfWork.Setup(m => m.Urls).Returns(mockRepo.Object);
var sut = new UrlController(mockUnitOfWork.Object);
//Act
var actionResult = sut.Get(testId) as OkNegotiatedContentResult<Url>;
//Assert
Assert.IsNotNull(actionResult);
Assert.AreEqual(expected, actionResult.Content);
}
}
Moq is flexible enough that you could also mock the entire dependency call so that you don't necessarily have to mock the repository if you have no need for more complicated setups.
The test would then be rewritten to
[TestClass]
public class UrlControllerTests {
[TestMethod]
public void Get_With_Valid_Id_Should_Return_Url() {
//Arrange
var testId = 5;
var expected = new Url { Id = testId };
var mockUnitOfWork = new Mock<IUnitOfWork>();
mockUnitOfWork.Setup(m => m.Urls.Get(testId)).Returns(expected);
var sut = new UrlController(mockUnitOfWork.Object);
//Act
var actionResult = sut.Get(testId) as OkNegotiatedContentResult<Url>;
//Assert
Assert.IsNotNull(actionResult);
Assert.AreEqual(expected, actionResult.Content);
}
}

Is it possible to unit test BundleConfig in MVC4?

As far as I can tell, the answer is no. The issue I'm seeing comes from the Include(params string[]) method in the System.Web.Optimization.Bundle class. Internally this invokes System.Web.Optimization.IncludeDirectory(string, string, bool), which in turn uses this code:
DirectoryInfo directoryInfo = new DirectoryInfo(
HttpContext.Current.Server.MapPath(directoryVirtualPath));
While it is possible to set HttpContext.Current during a unit test, I can't figure out how to make its .Server.MapPath(string directoryVirtualPath) return a non-null string. Since the DirectoryInfo(string) constructor throws an exception when passed a null argument, such a test will always fail.
What is the .NET team's recommendation for this? Do we have to unit test bundling configurations as part of integration tests or user acceptance tests?
I have some good news for you, for RTM we added a new static property on BundleTable to enable more unit tests:
public static Func<string, string> MapPathMethod;
Edit Updated with a test virtual path provider:
So you can do something like this:
public class TestVirtualPathProvider : VirtualPathProvider {
private string NormalizeVirtualPath(string virtualPath, bool isDirectory = false) {
if (!virtualPath.StartsWith("~")) {
virtualPath = "~" + virtualPath;
}
virtualPath = virtualPath.Replace('\\', '/');
// Normalize directories to always have an ending "/"
if (isDirectory && !virtualPath.EndsWith("/")) {
return virtualPath + "/";
}
return virtualPath;
}
// Files on disk (virtualPath -> file)
private Dictionary<string, VirtualFile> _fileMap = new Dictionary<string, VirtualFile>();
private Dictionary<string, VirtualFile> FileMap {
get { return _fileMap; }
}
public void AddFile(VirtualFile file) {
FileMap[NormalizeVirtualPath(file.VirtualPath)] = file;
}
private Dictionary<string, VirtualDirectory> _directoryMap = new Dictionary<string, VirtualDirectory>();
private Dictionary<string, VirtualDirectory> DirectoryMap {
get { return _directoryMap; }
}
public void AddDirectory(VirtualDirectory dir) {
DirectoryMap[NormalizeVirtualPath(dir.VirtualPath, isDirectory: true)] = dir;
}
public override bool FileExists(string virtualPath) {
return FileMap.ContainsKey(NormalizeVirtualPath(virtualPath));
}
public override bool DirectoryExists(string virtualDir) {
return DirectoryMap.ContainsKey(NormalizeVirtualPath(virtualDir, isDirectory: true));
}
public override VirtualFile GetFile(string virtualPath) {
return FileMap[NormalizeVirtualPath(virtualPath)];
}
public override VirtualDirectory GetDirectory(string virtualDir) {
return DirectoryMap[NormalizeVirtualPath(virtualDir, isDirectory: true)];
}
internal class TestVirtualFile : VirtualFile {
public TestVirtualFile(string virtualPath, string contents)
: base(virtualPath) {
Contents = contents;
}
public string Contents { get; set; }
public override Stream Open() {
return new MemoryStream(UTF8Encoding.Default.GetBytes(Contents));
}
}
internal class TestVirtualDirectory : VirtualDirectory {
public TestVirtualDirectory(string virtualPath)
: base(virtualPath) {
}
public List<VirtualFile> _directoryFiles = new List<VirtualFile>();
public List<VirtualFile> DirectoryFiles {
get {
return _directoryFiles;
}
}
public List<VirtualDirectory> _subDirs = new List<VirtualDirectory>();
public List<VirtualDirectory> SubDirectories {
get {
return _subDirs;
}
}
public override IEnumerable Files {
get {
return DirectoryFiles;
}
}
public override IEnumerable Children {
get { throw new NotImplementedException(); }
}
public override IEnumerable Directories {
get {
return SubDirectories;
}
}
}
And then write a unit test using that like so:
[TestMethod]
public void StyleBundleCustomVPPIncludeVersionSelectsTest() {
//Setup the vpp to contain the files/directories
TestVirtualPathProvider vpp = new TestVirtualPathProvider();
var directory = new TestVirtualPathProvider.TestVirtualDirectory("/dir/");
directory.DirectoryFiles.Add(new TestVirtualPathProvider.TestVirtualFile("/dir/style1.0.css", "correct"));
directory.DirectoryFiles.Add(new TestVirtualPathProvider.TestVirtualFile("/dir/style.css", "wrong"));
vpp.AddDirectory(directory);
// Setup the bundle
ScriptBundle bundle = new ScriptBundle("~/bundles/test");
bundle.Items.VirtualPathProvider = vpp;
bundle.Include("~/dir/style{version}.css");
// Verify the bundle repsonse
BundleContext context = SetupContext(bundle, vpp);
BundleResponse response = bundle.GetBundleResponse(context);
Assert.AreEqual(#"correct", response.Content);
}
In .Net 4.5 things have slightly changed. Here is a working version of the approved answer updated to accommodate these changes (I am using Autofac). Note the "GenerateBundleResponse" instead of "GetBundleResponse":
[Fact]
public void StyleBundleIncludesVersion()
{
//Setup the vpp to contain the files/directories
var vpp = new TestVirtualPathProvider();
var directory = new TestVirtualPathProvider.TestVirtualDirectory("/dir/");
directory.DirectoryFiles.Add(new TestVirtualPathProvider.TestVirtualFile("/dir/style1.0.css", "correct"));
directory.DirectoryFiles.Add(new TestVirtualPathProvider.TestVirtualFile("/dir/style.css", "wrong"));
vpp.AddDirectory(directory);
// Setup the bundle
var bundleCollection = new BundleCollection();
var bundle = new ScriptBundle("~/bundles/test");
BundleTable.VirtualPathProvider = vpp;
bundle.Include("~/dir/style{version}.css");
bundleCollection.Add(bundle);
var mockHttpContext = new Mock<HttpContextBase>();
// Verify the bundle repsonse
var context = new BundleContext(mockHttpContext.Object, bundleCollection, vpp.ToString());
var response = bundle.GenerateBundleResponse(context);
Assert.Equal(#"correct", response.Content);
}

Add coded control to UIMap (Coded UI Test)

I would like to add a handwritten coded control to my UIMap.cs (not UIMap.Designer.cs).
For example, when I record: writing in a texBox, I get the following code in UIMap.Designer.cs:
public class Recorded_Writing_In_forRecordParams
{
public string UIForRecordEditText = "forRecord";
}
public class UIMainWindowWindow : WpfWindow
{
public UIMainWindowWindow()
{
this.SearchProperties[WpfWindow.PropertyNames.Name] = "MainWindow";
this.SearchProperties.Add(new PropertyExpression(WpfWindow.PropertyNames.ClassName, "HwndWrapper", PropertyExpressionOperator.Contains));
this.WindowTitles.Add("MainWindow");
}
public WpfEdit UIForRecordEdit
{
get
{
if ((this.mUIForRecordEdit == null))
{
this.mUIForRecordEdit = new WpfEdit(this);
this.mUIForRecordEdit.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "forRecord";
this.mUIForRecordEdit.WindowTitles.Add("MainWindow");
}
return this.mUIForRecordEdit;
}
}
private WpfEdit mUIForRecordEdit;
}
I want use this control in my CodedUITest. Is there a way to search the TextBox in the UIMap.cs by own coded or to search it in my TestMethod? Which is the best way?
Thanks for the answer, but I solved my problem on my own with the following way:
UIMap.cs
public partial class TestLittleAppUIMap
{
private MyWindow mMyWindow;
public MyWindow MMyWindow
{
get
{
if (this.mMyWindow == null)
{
this.mMyWindow = new MyWindow();
}
return this.mMyWindow;
}
}
}
public class MyWindow : WpfWindow
{
private WpfEdit mWpfEdit;
public MyWindow()
{
this.SearchProperties[WpfWindow.PropertyNames.Name] = "MainWindow";
this.SearchProperties.Add(new PropertyExpression(WpfWindow.PropertyNames.ClassName, "HwndWrapper", PropertyExpressionOperator.Contains));
this.WindowTitles.Add("MainWindow");
}
public WpfEdit MWpfEdit
{
get
{
if ((this.mWpfEdit == null))
{
this.mWpfEdit = new WpfEdit(this);
#region Search Criteria
this.mWpfEdit.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "forOwn";
this.mWpfEdit.WindowTitles.Add("MainWindow");
#endregion
}
return this.mWpfEdit;
}
}
CodedUI Test
[TestMethod]
public void TestLittleAppOwnMap()
{
this.UIMap.MMyWindow.MWpfEdit.DrawHighlight();
Playback.Wait(2500);
}
It is almost a copy of the designer class.
For searching directly in the TestMethod you can go like this:
[TestMethod]
public void TestLittleAppOwn()
{
WpfWindow w = new WpfWindow();
w.SearchProperties[WpfWindow.PropertyNames.Name] = "MainWindow";
w.SearchProperties.Add(new PropertyExpression(WpfWindow.PropertyNames.ClassName, "HwndWrapper", PropertyExpressionOperator.Contains));
w.DrawHighlight();
WpfEdit e = new WpfEdit(w);
e.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "forOwn";
e.SetProperty("Text","myText");
e.DrawHighlight();
Playback.Wait(2500);
}
Where Playback.Wait just wait a short time for showing the Highlight.

Mock with Rhino mock -MVVM

I am using Rhino mock for mocking in my test methods. Could someone please see the TODO part in the test method and help me to mock it?
This is my service interface:
public interface ICustomersServiceAgent
{
void GetCustomers(EventHandler<GetCustomersCompletedEventArgs> callback);
void SaveCustomer(POC.Model.Customer cust, EventHandler<SaveCustomerCompletedEventArgs> callback);
}
This is my ViewModel
public class CustomerVM : ViewModelBase
{
private Model.Customer _curentCustomer;
private RelayCommand _saveCommand;
private ICustomersServiceAgent ServiceAgent { get; set; }
private bool isSaved;
private RelayCommand _calculateAgeCommand;
private Decimal age;
private DateTime dateOfBirth;
public CustomerVM(ICustomersServiceAgent serviceAgent)
{
if (serviceAgent == null)
{
ServiceAgent = ServiceManager.GetCustomerServiceManagement();
}
else
{
ServiceAgent =serviceAgent;
}
WireCommands();
}
// if curent object is null then it should be intialize
public Model.Customer CurentCustomer
{
get { return _curentCustomer ?? (_curentCustomer = new Model.Customer()); }
set
{
if (_curentCustomer != value)
{
_curentCustomer = value;
OnPropertyChanged("CurentCustomer");
}
}
}
public RelayCommand CalculateAgeCommand
{
get;
private set;
}
private void WireCommands()
{
SaveCustomerCommand = new RelayCommand(SaveCustomer);
SaveCustomerCommand.IsEnabled = true;
CalculateAgeCommand = new RelayCommand(CalculateAge);
}
private void SaveCustomer()
{
var cus = CurentCustomer;
ServiceAgent.SaveCustomer(cus, (s, e) =>
{
IsSaved = e.Result;
});
}
private void CalculateAge()
{
Age = DateTime.Now.Year - DateOfBirth.Year;
}
public RelayCommand SaveCustomerCommand
{
get;
private set;
}
public bool IsSaved
{
get { return isSaved; }
set
{
isSaved = value;
OnPropertyChanged("IsSaved");
}
}
public decimal Age
{
get { return age; }
set {
age = value;
OnPropertyChanged("Age");
}
}
public DateTime DateOfBirth
{
get { return dateOfBirth; }
set {
dateOfBirth = value;
OnPropertyChanged("DateOfBirth");
}
}
}
I want to test the SaveCustomerCommand in ViewModel above.
So In the my test method, I want to mock the void SaveCustomer(POC.Model.Customer cust, EventHandler<SaveCustomerCompletedEventArgs> callback) method in the ICustomersServiceAgent interface.
This is my test method, see the ToDo part
[TestMethod]
public void SaveCustomerCommandTest()
{
var customerServiceMock = MockRepository.GenerateMock<ICustomersServiceAgent>();
var customerVM = new POC.SilverlightClient.ViewModel.CustomerVM(customerServiceMock);
// TO do : Code to mock SaveCustomer method ///////////////////////////////////
var saveCustomerCommand = customerVM.SaveCustomerCommand;
saveCustomerCommand.Execute(null);
Assert.IsTrue(customerVM.IsSaved);
}
Could someone please explain how I can do this?
I don't see why you need to mock SaveCustomer. All the private SaveCustomer method does is invoke the ServiceAgent service which you already are mocking. I assume the RelayCommand class invokes the delegate you're sending in the constructor parameter which is the call to SaveCustomer. Have you tried running the unit test in your question as-is?
Try following:
customerServiceMock.Stub(sa => sa.SaveCustomer(Arg<POC.Model.Customer>.Is.Anything, Arg<EventHandler<SaveCustomerCompletedEventArgs>>.Is.Anything)).WhenCalled(invocation =>
{
((EventHandler<SaveCustomerCompletedEventArgs>)invocation.Arguments[1])(
customerServiceMock,
new SaveCustomerCompletedEventArgs { Result = true });
});