Moq with Func<Foo, Task<List<Bar>>>> - c#

Scenario:
We are in the lovely scenario of a terrible data source that requires an arcane syntax. We have built our "repository" layer to translate simple parameters (primitive values) into the correct syntax for the destination.
We would like to unit test that:
The correct filters have been applied (can be done by checking the string that the repo's helper methods create)
The (mocked) remote data source is called exactly once
The (mocked) data we have defined the remote data source as returning is passed back as the return value when we call the repo.
For example
var expectedReturn = new List<Product> { new Product { StockNumber = "123" } };
provider.Setup(x => x.Run(It.IsAny<Func<IRemoteClient, Task<List<Product>>>>(),
It.IsAny<string>())).ReturnsAsync(expectedReturn);
Moq is failing on the Setup line with a NotSupportedException. I've read probably a dozen or more SO posts and can't find out why it doesn't work.
In normal usage, the Repo will use something like:
provider.Run(x => x.GetAsync<List<Product>>(requestBuilder.Request), "foo")
Definition of run in provider interface:
Task<T> Run<T>(Func<IRemoteClient, Task<T>> action, string name);
Since the requestBuilder is injected as well, we can easily evaluate that the request is built correctly as far as the number and type of parameters, but we can't run the test at all because the Mock call fails the setup and so we never get there.

I am using Moq 4.9.0 and have tested this both on .NET Core 2.1, as well as inside LINQPad using the .NET Framework. It compiles and runs for me without any problems. I am able to run the mock setup, and I am also able to call the mocked method on the mock object, and retrieve the expected return result.
The following is my test code:
class Program
{
static void Main(string[] args)
{
var expectedReturn = new List<Product> { new Product { StockNumber = "123" } };
var provider = new Mock<IProvider>();
provider
.Setup(x => x.Run(
It.IsAny<Func<IRemoteClient, Task<List<Product>>>>(),
It.IsAny<string>()))
.ReturnsAsync(expectedReturn);
var result = provider.Object.Run(client => client.GetAsync<List<Product>>(null), "foo");
Console.WriteLine(result.Result[0].StockNumber);
}
}
public interface IProvider
{
Task<T> Run<T>(Func<IRemoteClient, Task<T>> action, string name);
}
public interface IRemoteClient
{
Task<T> GetAsync<T>(object request);
}
public class Product
{
public string StockNumber { get; set; }
}

Related

How to mock IMapper which is calling inside foreachloop?

C# method where I am using IMapper interface
foreach (var req in listRequestMasters)
{
var customReq = _mapper.Map<GridModel>(req);
}
by below line of code getting success assertion but not as expected result, the one record getting twice
_mockMapper.Setup(x => x.Map<GridModel>(It.IsAny<RequestMaster>())).Returns(requestGridModelMockData.FirstOrDefault());
and by below line of code getting
Message:
Moq.MockException : IMapperBase.Map(RequestMaster)
invocation failed with mock behavior Strict. All invocations on the
mock must have a corresponding setup.
_mockMapper.Setup(x => x.Map<List<GridModel>>(It.IsAny<RequestMaster>())).Returns(requestGridModelMockData);
remaining code
var result = await Service.GetHistoryRequestDetails(historyVMMockData);
Assert.Equal(JsonConvert.SerializeObject(requestGridModelMockData), JsonConvert.SerializeObject(result));
AutoMapper is a library that is already well tested on its own. So you should use the AutoMapper library also in your tests and not mock it, because you want to test your code and not others library code (or do you have also self written tests for ASP core, EF or something similar?).
In most environments you manage your mapping within individual Profiles. If not, you should do so and create within your test a fresh mapper (preferable in constructor) and use it as usual.
For example you have some DTOs:
public class Source
{
public string Name { get; set; }
}
public class Destination
{
public string Name { get; set; }
}
And somewhere else you defined the AutoMapper mappings:
public class MyProfile : Profile
{
public MyProfile()
{
CreateMap<Source, Destination>();
}
}
Then within your test class you do something like this:
public class MyTests
{
private readonly IMapper mapper;
public MyTests()
{
var config = new MapperConfiguration(cfg => cfg.AddProfile<MyProfile>());
var mapper = config.CreateMapper();
}
[Fact]
public void TestSomething()
{
var source = new Source { Name = "foo" };
var sut = new SystemUnderTest(mapper);
var result = sut.DoSomething(source);
var expected = mapper.Map<Dest>(source);
Assert.Equal(expected, result, DestinationComparer.Default);
}
}
As you can see, the system under test receives the real mapper (even if you just care for an IMapper interface). You don't create a mock, stub, puppet, you name it for 3rd party libraries. You use the real implemenations, because you write tests for your code.
Maybe it makes sense to write tests checking if a 3rd party library works as expected, which helps narrow problems down when upgrading a library and still behaves the same. But these tests don't use anything of your code and just tests some library function:
[Fact]
public void CheckMapperMapsCorrectly()
{
var source = new Source { Name = "Foo" };
var dest = mapper.Map<Destination>(source);
Assert.Equal(source.Name, dest.Name);
}
But that is something different and fully optional, depending on how much you trust each 3rd party library or makes sense if you already fall into that pit on an upgrade of a 3rd party library to avoid the same problem on next update.

Mock with 'dynamic' generic and anonymous object 'new {}' fails

Visual Studio 2019 Enterprise 16.9.4; Moq 4.16.1; xunit 2.4.1; net5.0
I'm trying to unit test my AlbumData.GetAlbumsAsync() method. I mock the SqlDataAccess layer which is making a call to the DB using Dapper in a generic method.
This is my setup. The mock is not working. In the AlbumData.GetAlbumsAsync() method the call to the mocked object (_sql.LoadDataAsync) returns null and output is set to null.
Can anyone tell me what I'm dong wrong?
SqlDataAccess.cs
public async Task<List<T>> LoadDataAsync<T, U>(string storedProcedure,
U parameters, string connectionStringName)
{
string connectionString = GetConnectionString(connectionStringName);
using (IDbConnection connection = new SqlConnection(connectionString))
{
IEnumerable<T> result = await connection.QueryAsync<T>(storedProcedure, parameters,
commandType: CommandType.StoredProcedure);
List<T> rows = result.ToList();
return rows;
}
}
AlbumData.cs
public class AlbumData : IAlbumData
{
private readonly ISqlDataAccess _sql;
public AlbumData(ISqlDataAccess sql)
{
_sql = sql;
}
public async Task<List<AlbumModel>> GetAlbumsAsync()
{
var output = await _sql.LoadDataAsync<AlbumModel, dynamic>
("dbo.spAlbum_GetAll", new { }, "AlbumConnection");
return output;
}
...
}
AlbumDataTest.cs
public class AlbumDataTest
{
private readonly List<AlbumModel> _albums = new()
{
new AlbumModel { Title = "Album1", AlbumId = 1 },
new AlbumModel { Title = "Album2", AlbumId = 2 },
new AlbumModel { Title = "Album3", AlbumId = 3 }
};
[Fact]
public async Task getAlbums_returns_multiple_records_test()
{
Mock<ISqlDataAccess> sqlDataAccessMock = new();
sqlDataAccessMock.Setup(d => d.LoadDataAsync<AlbumModel, dynamic>
(It.IsAny<string>(), new { }, It.IsAny<string>()))
.Returns(Task.FromResult(_albums));
AlbumData albumData = new AlbumData(sqlDataAccessMock.Object);
List<AlbumModel> actual = await albumData.GetAlbumsAsync();
Assert.True(actual.Count == 3);
}
...
}
UPDATE1:
Following #freeAll and #brent.reynolds suggestions I updated the test to use It.IsAny<string>()
Also updated #brent.reynolds fiddle to actually implement a unit test:
https://dotnetfiddle.net/nquthR
It all works in the fiddle but when I paste the exact same test into my AlbumDataTest it still returns null. Assert.Null(actual); passes, Assert.True(actual.Count == 3); fails.
UPDATE2:
I've posted a project with the failing test to https://github.com/PerProjBackup/Failing-Mock.
If you run the API.Library.ConsoleTests project the Mock works. If you run the tests in the API.Library.Tests project with the Test Explorer the Mock fails.
#brent.reynolds was able to get the Mock to work by changing the dynamic generic to object. Now trying to debug the dynamic issue.
UPDATE3:
If I move the AlbumData class into the same project as the AllbumDataTest class the mock works (using dynamic) returning the list with three objects. But when the AlbumData class is in a separate project (as it would be in the real world) the mock returns null.
I've updated the https://github.com/PerProjBackup/Failing-Mock repository. I deleted the console app and created a Failing and Passing folder with the two scenarios.
Why would the class that the mock is being passed to being in a different project make the mock fail?
UPDATE4:
See brent.reynolds accepted answer and my comment there. Issue was the use of an anonymous object in the the mock setup. I've deleted the Failing-Mock repository and the dotnetfiddle.
It might be related to the async method. According to the documentation for async methods, You can either do
sqlDataAccessMock
.Setup(d => d.LoadDataAsync<AlbumModel, dynamic>(
It.IsAny<string>(),
new {},
It.IsAny<string>())
.Result)
.Returns(_albums);
or
sqlDataAccessMock
.Setup(d => d.LoadDataAsync<AlbumModel, dynamic>(
It.IsAny<string>(),
new {},
It.IsAny<string>()))
.ReturnsAsync(_albums);
Edited:
Try adding It.IsAny<object>() to the setup:
sqlDataAccessMock
.Setup(d => d.LoadDataAsync<AlbumModel, object>(
It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<string>()))
.Returns(Task.FromResult(_albums));
and changing the type parameter in GetAlbumsAsync() to:
var output = await _sql.LoadDataAsync<AlbumModel, object>(
"dbo.spAlbum_GetAll",
new { },
"AlbumConnection");
OP Note/Summary:
The use of an anonymous object new {} in the mock setup is the central issue. It works when the test class and class being tested are in the same project but not when they are in separate projects since it cannot then be reused. It.IsAny<dynamic>() will not work because the compiler forbids dynamic inside LINQ expression trees. brent.reynolds use of object resolves the issue.
Use It.IsAny<string>() instead of the empty strings
sqlDataAccessMock.Setup(d => d.LoadDataAsync<AlbumModel, dynamic>
(It.IsAny<string>(), new { }, It.IsAny<string>())).Returns(Task.FromResult(_albums));
Note: you can't use It.IsAny<T>() on dynamic objects

Unit Testing a controller that uses windows authentication

-------Please see updates below as I now have this set up for dependency injection and the use of the MOQ mocking framework. I'd still like to split up my repository so it doesn't directly depend on pulling the windowsUser within the same function.
I have a Web API in an intranet site that populates a dropdown. The query behind the dropdown takes the windows username as a parameter to return the list.
I realize I don't have all of this set up correctly because I'm not able to unit test it. I need to know how this "should" be set up to allow unit testing and then what the unit tests should look like.
Additional info: this is an ASP.NET MVC 5 application.
INTERFACE
public interface ITestRepository
{
HttpResponseMessage DropDownList();
}
REPOSITORY
public class ExampleRepository : IExampleRepository
{
//Accessing the data through Entity Framework
private MyDatabaseEntities db = new MyDatabaseEntities();
public HttpResponseMessage DropDownList()
{
//Get the current windows user
string windowsUser = HttpContext.Current.User.Identity.Name;
//Pass the parameter to a procedure running a select query
var sourceQuery = (from p in db.spDropDownList(windowsUser)
select p).ToList();
string result = JsonConvert.SerializeObject(sourceQuery);
var response = new HttpResponseMessage();
response.Content = new StringContent(result, System.Text.Encoding.Unicode, "application/json");
return response;
}
}
CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
public ExampleController()
{
_exampleRepository = new ExampleRepository();
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 1
I have updated my Controller based on BartoszKP's suggestion to show dependency injection.
UPDATED CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
//Dependency Injection
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 2
I have decided to use MOQ as a mocking framework for unit testing. I'm able to test something simple, like the following. This would test a simple method that doesn't take any parameters and doesn't include the windowsUser part.
[TestMethod]
public void ExampleOfAnotherTest()
{
//Arrange
var mockRepository = new Mock<IExampleRepository>();
mockRepository
.Setup(x => x.DropDownList())
.Returns(new HttpResponseMessage(HttpStatusCode.OK));
ExampleController controller = new ExampleController(mockRepository.Object);
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
//Act
var response = controller.DropDownList();
//Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
I need help testing the DropDownList method (one that does include code to get the windowsUser). I need advice on how to break this method apart. I know both parts shouldn't been in the same method. I don't know how to arrange splitting out the windowsUser variable. I realize this really should be brought in as a parameter, but I can't figure out how.
You usually do not unit-test repositories (integration tests verify if they really persist the data in the database correctly) - see for example this article on MSDN:
Typically, it is difficult to unit test the repositories themselves, so it is often better to write integration tests for them.
So, let's focus on testing only the controller.
Change the controller to take IExampleRepository in its constructor as a parameter:
private IExampleRepository _exampleRepository;
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
Then, in your unit tests, use one of mocking frameworks (such as RhinoMock for example) to create a stub for the sole purpose of testing the controller.
[TestFixture]
public class ExampleTestFixture
{
private IExampleRepository CreateRepositoryStub(fake data)
{
var exampleRepositoryStub = ...; // create the stub with a mocking framework
// make the stub return given fake data
return exampleRepositoryStub;
}
[Test]
public void GivenX_WhenDropDownListIsRequested_ReturnsY()
{
// Arrange
var exampleRepositoryStub = CreateRepositoryStub(X);
var exampleController = new ExampleController(exampleRepositoryStub);
// Act
var result = exampleController.DropDownList();
// Assert
Assert.That(result, Is.Equal(Y));
}
}
This is just a quick&dirty example - CreateRepositoryStub method should be of course extracted to some test utility class. Perhaps it should return a fluent interface to make the test's Arrange section more readable on what is given. Something more like:
// Arrange
var exampleController
= GivenAController()
.WithFakeData(X);
(with better names that reflect your business logic of course).
In case of ASP.NET MVC, the framework needs to know how to construct the controller. Fortunately, ASP.NET supports the Dependency Injection paradigm and a parameterless constructor is not required when using MVC unity.
Also, note the comment by Richard Szalay:
You shouldn't use HttpContext.Current in WebApi - you can use base.User which comes from HttpRequestBase.User and is mockable. If you really want to continue using HttpContext.Current, take a look at Mock HttpContext.Current in Test Init Method
One trick that I find very useful when trying to make old code testable when said code is accessing some global static or other messy stuff that I can't easily just parameterize is to wrap access to the resource in a virtual method call. Then you can subclass your system under test and use that in the unit test instead.
Example, using a hard dependency in the System.Random class
public class Untestable
{
public int CalculateSomethingRandom()
{
return new Random().Next() + new Random().Next();
}
}
Now we replace var rng = new Random();
public class Untestable
{
public int CalculateSomethingRandom()
{
return GetRandomNumber() + GetRandomNumber();
}
protected virtual int GetRandomNumber()
{
return new Random().Next();
}
}
Now we can create a testable version of the class:
public class Testable : Untestable
{
protected override int GetRandomNumber()
{
// You can return whatever you want for your test here,
// it depends on what type of behaviour you are faking.
// You can easily inject values here via a constructor or
// some public field in the subclass. You can also add
// counters for times method was called, save the args etc.
return 4;
}
}
The drawback with this method is that you can't use (most) isolation frameworks to implement protected methods (easily), and for good reason, since protected methods are sort of internal and shouldn't be all that important to your unit tests. It's still a really handy way of getting things covered with tests so you can refactor them, instead of having to spend 10 hours without tests, trying to do major architectual changes to your code before you get to "safety".
Just another tool to keep in mind, I find it comes in handy from time to time!
EDIT: More concretely, in your case you might want to create a protected virtual string GetLoggedInUserName(). This will technically speaking keep the actual call to HttpContext.Current.User.Identity.Name untested, but you will have isolated it to the simplest smallest possible method, so you can test that the code is calling the correct method the right amount of times with the correct args, and then you simply have to know that HttpContext.Current.User.Identity.Name contains what you want. This can later be refactored into some sort of user manager or logged in user provider, you'll see what suits best as you go along.

Manipulating objects with DbSet<T> and IQueryable<T> with NSubstitute returns error

I'd like to use NSubstitute to unit test Entity Framework 6.x by mocking DbSet. Fortunately, Scott Xu provides a good unit testing library, EntityFramework.Testing.Moq using Moq. So, I modified his code to be suitable for NSubstitute and it's been looking good so far, until I wanted to test DbSet<T>.Add(), DbSet<T>.Remove() methods. Here's my code bits:
public static class NSubstituteDbSetExtensions
{
public static DbSet<TEntity> SetupData<TEntity>(this DbSet<TEntity> dbset, ICollection<TEntity> data = null, Func<object[], TEntity> find = null) where TEntity : class
{
data = data ?? new List<TEntity>();
find = find ?? (o => null);
var query = new InMemoryAsyncQueryable<TEntity>(data.AsQueryable());
((IQueryable<TEntity>)dbset).Provider.Returns(query.Provider);
((IQueryable<TEntity>)dbset).Expression.Returns(query.Expression);
((IQueryable<TEntity>)dbset).ElementType.Returns(query.ElementType);
((IQueryable<TEntity>)dbset).GetEnumerator().Returns(query.GetEnumerator());
#if !NET40
((IDbAsyncEnumerable<TEntity>)dbset).GetAsyncEnumerator().Returns(new InMemoryDbAsyncEnumerator<TEntity>(query.GetEnumerator()));
((IQueryable<TEntity>)dbset).Provider.Returns(query.Provider);
#endif
...
dbset.Remove(Arg.Do<TEntity>(entity =>
{
data.Remove(entity);
dbset.SetupData(data, find);
}));
...
dbset.Add(Arg.Do<TEntity>(entity =>
{
data.Add(entity);
dbset.SetupData(data, find);
});
...
return dbset;
}
}
And I created a test method like:
[TestClass]
public class ManipulationTests
{
[TestMethod]
public void Can_remove_set()
{
var blog = new Blog();
var data = new List<Blog> { blog };
var set = Substitute.For<DbSet<Blog>, IQueryable<Blog>, IDbAsyncEnumerable<Blog>>()
.SetupData(data);
set.Remove(blog);
var result = set.ToList();
Assert.AreEqual(0, result.Count);
}
}
public class Blog
{
...
}
The issue arises when the test method calls set.Remove(blog). It throws an InvalidOperationException with error message of
Collection was modified; enumeration operation may not execute.
This is because the fake data object has been modified when the set.Remove(blog) method is called. However, the original Scott's way using Moq doesn't result in the issue.
Therefore, I wrapped the set.Remove(blog) method with a try ... catch (InvalidOperationException ex) block and let the catch block do nothing, then the test doesn't throw an exception (of course) and does get passed as expected.
I know this is not the solution, but how can I achieve my goal to unit test DbSet<T>.Add() and DbSet<T>.Remove() methods?
What's happening here?
set.Remove(blog); - this calls the previously configured lambda.
data.Remove(entity); - The item is removed from the list.
dbset.SetupData(data, find); - We call SetupData again, to reconfigure the Substitute with the new list.
SetupData runs...
In there, dbSetup.Remove is being called, in order to reconfigure what happens when Remove is called next time.
Okay, we have a problem here. dtSetup.Remove(Arg.Do<T.... doesn't reconfigure anything, it rather adds a behavior to the Substitute's internal list of things that should happen when you call Remove. So we're currently running the previously configured Remove action (1) and at the same time, down the stack, we're adding an action to the list (5). When the stack returns and the iterator looks for the next action to call, the underlying list of mocked actions has changed. Iterators don't like changes.
This leads to the conclusion: We can't modify what a Substitute does while one of its mocked actions is running. If you think about it, nobody who reads your test would assume this to happen, so you shouldn't do this at all.
How can we fix it?
public static DbSet<TEntity> SetupData<TEntity>(
this DbSet<TEntity> dbset,
ICollection<TEntity> data = null,
Func<object[], TEntity> find = null) where TEntity : class
{
data = data ?? new List<TEntity>();
find = find ?? (o => null);
Func<IQueryable<TEntity>> getQuery = () => new InMemoryAsyncQueryable<TEntity>(data.AsQueryable());
((IQueryable<TEntity>) dbset).Provider.Returns(info => getQuery().Provider);
((IQueryable<TEntity>) dbset).Expression.Returns(info => getQuery().Expression);
((IQueryable<TEntity>) dbset).ElementType.Returns(info => getQuery().ElementType);
((IQueryable<TEntity>) dbset).GetEnumerator().Returns(info => getQuery().GetEnumerator());
#if !NET40
((IDbAsyncEnumerable<TEntity>) dbset).GetAsyncEnumerator()
.Returns(info => new InMemoryDbAsyncEnumerator<TEntity>(getQuery().GetEnumerator()));
((IQueryable<TEntity>) dbset).Provider.Returns(info => getQuery().Provider);
#endif
dbset.Remove(Arg.Do<TEntity>(entity => data.Remove(entity)));
dbset.Add(Arg.Do<TEntity>(entity => data.Add(entity)));
return dbset;
}
The getQuery lambda creates a new query. It always uses the captured list data.
All .Returns configuration calls use a lambda. In there, we create a new query instance and delegate our call there.
Remove and Add only modify our captured list. We don't have to reconfigure our Substitute, because every call reevaluates the query using the lambda expressions.
While I really like NSubstitute, I would strongly recommend looking into Effort, the Entity Framework Unit Testing Tool.
You would use it like this:
// DbContext needs additional constructor:
public class MyDbContext : DbContext
{
public MyDbContext(DbConnection connection)
: base(connection, true)
{
}
}
// Usage:
DbConnection connection = Effort.DbConnectionFactory.CreateTransient();
MyDbContext context = new MyDbContext(connection);
And there you have an actual DbContext that you can use with everything that Entity Framework gives you, including migrations, using a fast in-memory-database.

Approach to test public methods depending on private methods

I'm trying to add tests to a legacy code, and as I start to adding code, I get the feeling that something is wrong.
In the following code, the public method RegisterChange is calling two private methods to:
Get the object to store
Store the object
public class ChangeService {
IRepository repository;
public ChangeService(IRepository repository){
this.repository = repository;
}
public bool RegisterChange( int entityId ){
var entity = GetParsedEntity( entityId );
SaveEntity( entity );
return true;
}
private Entity GetParsedEntity( int id ) {
var entity = repository.GetEntityById( id );
return new Entity{ Name = entity.Name };
}
private void SaveEntity( Entity entity ) {
repository.Save( Entity );
}
}
public class ChangeServiceFact(){
[Fact]
public void When_valid_entity__Should_save_entity(){
var mock = new Mock<IRepository>();
var service = new ChangeService(mock.object);
var result = service.RegisterChange( 0 );
Assert.True(result);
}
}
So, when Im mocking the repository, I had to go and check the private method's code to know which operations to mock.
The problem that I'm seeing with this approach is that, because the code is testing not only the test subject (the public method) but also the private methods, is not clear which should be the test result by looking at the test subject (public method).
In the case that, later on, someone decide to modify one private method (like throwing an exception from GetParsedEntity), the test will continue to pass correctly, but the client code could fail because of this change.
In this particular case, Im using C#, XUnit and Moq, but I think is more a general testing question.
The problem that I'm seeing with this approach is that, because the code is testing not only the test subject (the public method) but also the private methods, is not clear which should be the test result by looking at the test subject (public method).
The test subject you mention has no visible effect without knowing its full contract. What the full contract here is? The mentioned public method and constructor, which takes dependency. It's the dependency that's important here and interaction with this dependency is what should be tested. Private methods are (as always) implementation detail - irrelevant to unit testing.
Having said that, let's get back to the contract. What is the actual contract of test subject (ChangeService method)? To retrieve object from repository basing on some id, create different object and save the later in the same repository. And this is your test.
[Fact]
public void ChangeService_StoresNewEntityInRepository_BasedOnProvidedId()
{
const string ExpectedName = "some name";
var otherEntity = new OtherEntity { Name = ExpectedName };
var mock = new Mock<IRepository>();
var service = new ChangeService(mock.object);
mock.Setup(m => m.GetEntityById(0)).Return(otherEntity);
service.RegisterChange(0);
mock.Verify(m => m.SaveEntity(It.Is<Entity>(e => e.Name == ExpectedName));
}

Categories