Automoq Documentation - unit-testing

I am getting started with Automoq. I was trying to do something like this:
mocker.GetMock<IMyObjectToTweak>();
var line = mocker.Resolve<IMyObjectToTweak>();
line.PropertyOne = .75;
line.PropertyTwo = 100;
MyCalc calc = new MyCalc();
calc.Multiply(line);
Assert.AreEqual(75, line.result);
This runs bu fails. My properties do not get set. Am I missing the idea of Automoq? What is a good resource/tutorial?

To set property with Moq (this is what Automoq uses to create mock objects) you have to use different calls, - Setup, SetupGet or SetupProperty:
var line = mocker.Resolve<IMyObjectToTweak>();
// each does the same thing - "tells" PropertyOne to return .75 upon get
line.Setup(l => l.PropertyOne).Returns(.75);
line.SetupGet(l => l.PropertyOne).Returns(.75);
line.SetupProperty(l => l.PropertyOne, .75);

I suggest expose a Result property in your Sut (System Under test)
[TestClass]
public class SomeTest : ControllerTestBase
{
[TestMethod]
public void MethodNameOrSubject_ScenarioOrCondition_ExpectedBehaviourOrReturnValue()
{
var mock = _autoMoqContainer.GetMock<IMyObjectToTweak>();
var line = _autoMoqContainer.Resolve<IMyObjectToTweak>();
mock.Setup(x => x.PropertyOne).Returns(.75);
mock.Setup(x => x.PropertyTwo).Returns(100);
MyCalc calc = new MyCalc();
calc.Multiply(line);
Assert.AreEqual(75, calc.Result);
}
}
public interface IMyObjectToTweak
{
double PropertyOne { get; set; }
int PropertyTwo { get; set; }
}
public class MyCalc
{
public double Result { get; set; }
public void Multiply(IMyObjectToTweak line)
{
Result = line.PropertyOne*line.PropertyTwo;
}
}
Not related - But read my post more on AutoMocking
http://www.dotnetcurry.com/ShowArticle.aspx?ID=767

Related

Perform xUnit Moq test to create record and save it to DbContext

I am writing test for Web API application written in .NET CORE 3.1. I am using xUnit, AutoFixture & Moq for testing. I have a class that creates a new school instance in the database using Entity Framework/ DbContext. My question is how to mock dbContext & save changes, further my School DataModel has one: many relationships with SchoolBranch DataModel. I have followed this tutorial https://learn.microsoft.com/en-us/ef/ef6/fundamentals/testing/mocking
Error
Message:
Moq.MockException :
Expected invocation on the mock once, but was 0 times: m => m.Add<School>(It.IsAny<School>())
Performed invocations:
Mock<SchoolDbContext:1> (m):
No invocations performed.
Stack Trace:
Mock.Verify(Mock mock, LambdaExpression expression, Times times, String failMessage)
Mock`1.Verify[TResult](Expression`1 expression, Times times)
CreateSchoolCommandTest.ExecuteMethod_ShouldReturnNewGuidId_IfSuccess() line 50
School
public class School
{
public School()
{
this.SchoolBranches = new HashSet<SchoolBranch>();
}
public Guid SchoolID { get; set; }
public string Name { get; set; }
public ICollection<SchoolBranch> SchoolBranches { get; set; }
}
SchoolBranch
public class SchoolBranch
{
public SchoolBranch()
{
}
public Guid SchoolBranchID { get; set; }
public Guid SchoolID { get; set; }
public string Address { get; set; }
public int PhoneNumber { get; set; }
public School School { get; set; }
}
CreateSchool Class
public class CreateSchool : BaseCommand<Guid>, ICreateSchool
{
public SchoolDto SchoolDtos { get; set; }
public CreateSchool(IAppAmbientState appAmbient) : base(appAmbient) { }
public override Guid Execute()
{
try
{
var schoolId = Guid.NewGuid();
List<SchoolBranch> schoolBranches = new List<SchoolBranch>();
foreach(var item in SchoolDtos.SchoolBranchDtos)
{
schoolBranches.Add(new SchoolBranch()
{
SchoolBranchID = Guid.NewGuid(),
SchoolID = schoolId,
Address = item.Address,
PhoneNumber = item.PhoneNumber
});
}
var school = new School()
{
SchoolID = schoolId,
Name = SchoolDtos.Name,
SchoolBranches = schoolBranches
};
schoolDbContext.Schools.Add(school);
schoolDbContext.SaveChanges();
return school.SchoolID;
}
catch(Exception exp)
{
appAmbientState.Logger.LogError(exp);
throw;
}
}
}
Test Class
public class CreateSchoolCommandTest
{
private readonly ICreateSchool sut;
private readonly Mock<IAppAmbientState> appAmbientState = new Mock<IAppAmbientState>();
[Fact]
public void ExecuteMethod_ShouldReturnNewGuidId_IfSuccess()
{
//Arrange
var fixture = new Fixture();
var schoolDtoMock = fixture.Create<SchoolDto>();
var schoolDbSetMock = new Mock<DbSet<School>>();
var schoolBranchDbSetMock = new Mock<DbSet<SchoolBranch>>();
var schoolDbContextMock = new Mock<SchoolDbContext>();
//schoolDbSetMock.Setup(x => x.Add(It.IsAny<School>())).Returns((School s) => s); // this also did not work
schoolDbContextMock.Setup(m => m.Schools).Returns(schoolDbSetMock.Object);
//Act
sut.SchoolDtos = schoolDtoMock;
var actualDataResult = sut.Execute();
// Assert
Assert.IsType<Guid>(actualDataResult);
schoolDbContextMock.Verify(m => m.Add(It.IsAny<School>()), Times.Once());
schoolDbContextMock.Verify(m => m.SaveChanges(), Times.Once());
}
BaseCommand (DbContext is created here)
public abstract class BaseCommand<T>
{
protected SchoolDbContext schoolDbContext;
protected IAppAmbientState appAmbientState { get; }
public BaseCommand(IAppAmbientState ambientState)
{
this.schoolDbContext = new SchoolDbContext();
this.appAmbientState = ambientState;
}
public abstract T Execute();
}
For fix Error
You made just a little mistake. Insted of
schoolDbContextMock.Verify(m => m.Add(It.IsAny<School>()), Times.Once());
schoolDbContextMock.Verify(m => m.SaveChanges(), Times.Once());
You should have
schoolDbSetMock.Verify(m => m.Add(It.IsAny<School>()), Times.Once());
schoolDbContextMock.Verify(m => m.SaveChanges(), Times.Once());
Because you use method Add() on schoolDbContext.Schools not on schoolDbContext
For injecting dbContext
Your BaseCoommand class constructor should look like this:
public BaseCommand(IAppAmbientState ambientState, SchoolDbContext schoolDbContext)
{
this.schoolDbContext = schoolDbContext;
this.appAmbientState = ambientState;
}
Your CreateSchool class constructor:
public CreateSchool(IAppAmbientState appAmbient, SchoolDbContext schoolDbContext) : base(appAmbient, schoolDbContext) { }
And next in test you should initialize CreateSchool in test like this:
var sut = new CreateSchool(ambientState, schoolDbContextMock.Object);
And it will work

Unit testing view model that uses SelectMany to call an async method in ReactiveUI

I am new to ReactiveUI and trying to test a view model that looks like this:
public interface IService
{
Task<SessionModel> GetData(string id);
}
/// Provides a group of schedulers available to be used
public interface ISchedulers
{
IScheduler Default { get; }
IScheduler Dispatcher { get; }
}
public class MyVm : ReactiveObject
{
IService service;
public MyVm(ISchedulers schedulers, IService service)
{
this.service = service;
this.session = this.WhenAnyValue(x => x.SessionId)
.SelectMany(SearchSession)
.ObserveOn(schedulers.Default)
.ToProperty(this, x => x.Session);
}
private async Task<SessionModel> SearchSession(string id)
{
return await this.service.GetData(id);
}
private string sessionId;
public string SessionId
{
get => sessionId;
set => this.RaiseAndSetIfChanged(ref sessionId, value);
}
readonly ObservableAsPropertyHelper<SessionModel> session;
public SessionModel Session
{
get { return session.Value; }
}
}
public class SessionModel { }
I'm mocking the service call to return dummy data, but not sure what I need to do with a TestScheduler in order to get the SelectMany to work.
Here's a test class that shows how i would create a test for the view model. The goal is to eventually be able to check that the model got set:
[TestClass]
public class MyVmTests
{
[TestMethod]
public void CreateClass
{
var subject = new MyVm(/*pass in mocks*/);
subject.SessionId="test";
Assert.IsNotNull(subject.Session);
}
}
I don't think using TestScheduler is necessary. The following passes for me (using Moq):
var mockSchedulers = new Mock<ISchedulers>();
mockSchedulers.Setup(s => s.Default).Returns(Scheduler.Immediate);
var id = "123";
var mockService = new Mock<IService>();
var returnSession = new SessionModel();
mockService.Setup(s => s.GetData(It.Is<string>(i => i == id)))
.ReturnsAsync(returnSession);
var target = new MyVm(mockSchedulers.Object, mockService.Object);
target.SessionId = id;
Assert.IsNotNull(target.Session);
Assert.AreEqual(returnSession, target.Session);
TestScheduler is best when you're trying to test something with time (like a Delay, proving that the Delay actually happened). You're not really doing that here.

ASP.NET MVC unit testing with MOQ object

What is the best way to mock below code in unit testing:
public ActionResult Products()
{
ViewBag.Title = "Company Product";
IEnumerable<ProductDetailDto> productList = ProductService.GetAllEffectiveProductDetails();
ProductModels.ProductCategoryListModel model = new ProductModels.ProductCategoryListModel
{
//the type of ProductDetails => IEnumerable<productDetailDto>
ProductDetails = ProductService.GetAllEffectiveProductDetails(),
//the type of ProductCategoryList => IEnumerable<selectlistitem>
ProductCategoryList = productList.Select(x => new SelectListItem
{
Value = x.FKProductId.ToString(),
Text = x.Name
})
};
return View(model);
}
FYI, I am working on VS 2012, MVC 4.0, Unit Testing with MOQ object and TFS setup.
Can anyone help me out on this what is the best test method with mock object for above method?
If you want to mock ProductService first you need to inject this dependency.
Constructor injection is the most common approach for controllers in ASP.NET MVC.
public class YourController : Controller
{
private readonly IProductService ProductService;
/// <summary>
/// Constructor injection
/// </summary>
public YourController(IProductService productService)
{
ProductService = productService;
}
/// <summary>
/// Code of this method has not been changed at all.
/// </summary>
public ActionResult Products()
{
ViewBag.Title = "Company Product";
IEnumerable<ProductDetailDto> productList = ProductService.GetAllEffectiveProductDetails();
ProductModels.ProductCategoryListModel model = new ProductModels.ProductCategoryListModel
{
//the type of ProductDetails => IEnumerable<productDetailDto>
ProductDetails = ProductService.GetAllEffectiveProductDetails(),
//the type of ProductCategoryList => IEnumerable<selectlistitem>
ProductCategoryList = productList.Select(x => new SelectListItem
{
Value = x.FKProductId.ToString(),
Text = x.Name
})
};
return View(model);
}
}
#region DataModels
public class ProductDetailDto
{
public int FKProductId { get; set; }
public string Name { get; set; }
}
public class ProductModels
{
public class ProductCategoryListModel
{
public IEnumerable<ProductDetailDto> ProductDetails { get; set; }
public IEnumerable<SelectListItem> ProductCategoryList { get; set; }
}
}
#endregion
#region Services
public interface IProductService
{
IEnumerable<ProductDetailDto> GetAllEffectiveProductDetails()
}
public class ProductService : IProductService
{
public IEnumerable<ProductDetailDto> GetAllEffectiveProductDetails()
{
throw new NotImplementedException();
}
}
#endregion
Then you easily create a mock instance of IProductService, pass it into constructor of YourController, setup GetAllEffectiveProductDetails method and check returned ActionResult and its model.
[TestClass]
public class YourControllerTest
{
private Mock<IProductService> productServiceMock;
private YourController target;
[TestInitialize]
public void Init()
{
productServiceMock = new Mock<IProductService>();
target = new YourController(
productServiceMock.Object);
}
[TestMethod]
public void Products()
{
//arrange
// There is a setup of 'GetAllEffectiveProductDetails'
// When 'GetAllEffectiveProductDetails' method is invoked 'expectedallProducts' collection is exposed.
var expectedallProducts = new List<ProductDetailDto> { new ProductDetailDto() };
productServiceMock
.Setup(it => it.GetAllEffectiveProductDetails())
.Returns(expectedallProducts);
//act
var result = target.Products();
//assert
var model = (result as ViewResult).Model as ProductModels.ProductCategoryListModel;
Assert.AreEqual(model.ProductDetails, expectedallProducts);
/* Any other assertions */
}
}

Mocking ApiController which has Unit of work Dependency

I have a Apicontroller Which has dependency on unit of work object. How to write a test case for mocking ApiController Which has dependency on unit of work implemented in ApiController constructor.
Here is the code:
ApiController:
public class UserController : ApiController
{
public IUoW UoW { get; set; }
// GET api/user
public UserController(IUoW uow)
{
UoW = uow;
}
public IEnumerable<Users> Get()
{
return UoW.Users.Getall();
}
}
The Test case :
[TestMethod]
public void TestApiController()
{
var userManager = new Mock<IUoW>();
userManager.Setup(s => s.Users);
var controller = new UserController(userManager.Object);
var values = controller.Get();
Assert.IsNotNull(values);
}
The Users Class which has been mentioned here in UoW.Users is
public class UoW:IUoW,IDisposable
{
private MvcWebApiContext DbContext { get; set; }
protected IRepositoryProvider RepositoryProvider { get; set; }
private IRepository<T> GetStandardRepo<T>() where T : class
{
return RepositoryProvider.GetRepositoryForEntityType<T>();
}
public IRepository<Users> Users
{
get { return GetStandardRepo<Users>(); }
}
}
and the Users class itself is
[Table("UserProfile")]
public class Users
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
[DataType(DataType.PhoneNumber)]
public long Mobile { get; set; }
}
When I am trying to debug the test case , the Test case shows the object UoW.Users is null in UserController. Its obvious its not initializing through WebActivator since global.asax isnt invoked here through mock. Now how to write a successful test scenario in this context so that the WebApicontroller returns me the users object with data ?
Are you using Moq?
As I cannot see what type the UoW.Users property is I cannot demo how to mock it properly (updated IRepository) but that should be mocked and the GetAll method stubbed to return a sample list of users.
Updated
var userManager = new Mock<IUoW>();
userManager.Setup(s => s.Users).Returns(()=>
{
var userReposisitory = new Mock<IRepository<Users>>();
userReposisitory.Setup(ur => ur.GetAll()).Returns(()=> {
var listOfUsers = new List<Users>();
listOfUsers.Add(new Users { FirstName = "Example" });
return listOfUsers.AsQueryable();
});
return userReposisitory.Object;
});
var controller = new UserController(userManager.Object);
var result = controller.Get();
Assert.IsNotNull(result);
Assert.IsTrue(result.Count() > 0);

Unit testing of WF code activity

I have created coded activity and now I want to unit test it, but I do not know how.
Any example will be appreciated.
My simple example is below.
public sealed class ParameterActivity : CodeActivity
{
public InArgument<int> Argument1 { get; set; }
public InArgument<int> Argument2 { get; set; }
public OutArgument<int> Result { get; set; }
protected override void Execute(CodeActivityContext context)
{
var a = context.GetValue(Argument1);
var b = context.GetValue(Argument2);
context.SetValue(Result, a + b);
}
}
First of all, in case your activity returns a single value, just inherit from CodeActivity<TResult> and easily override Execute() with TResult as return type. Moreover, you've already available an OutArgument<TResult> Result.
public sealed class ParameterActivity : CodeActivity<int>
{
public InArgument<int> Argument1 { get; set; }
public InArgument<int> Argument2 { get; set; }
protected override int Execute(CodeActivityContext context)
{
var a = Argument1.Get(context);
var b = Argument2.Get(context);
return a + b;
}
}
That being said, WorkflowInvoker is the way to go to unit test almost all your activities. Taking above custom code activity as example:
[TestFixture]
public sealed class ParameterActivityTests
{
[Test]
public void ParameterActivity_Test()
{
var activity = new ParameterActivity();
var input1 = new Dictionary<string, object>
{
{ "Argument1", 10 },
{ "Argument2", 5 }
};
var input2 = new Dictionary<string, object>
{
{ "Argument1", -13 },
{ "Argument2", 3 }
};
var output1 = WorkflowInvoker.Invoke<int>(activity, input1);
var output2 = WorkflowInvoker.Invoke<int>(activity, input2);
Assert.That(output1, Is.EqualTo(15));
Assert.That(output2, Is.EqualTo(-10));
}
}
Rather than WorkflowInvoker you can also use WorkflowApplication but for unit testing that doesn't seem at all necessary when you just want to quickly invoke short-lived workflows for them to do "their thing" and return. Unless you want to test more elaborate stuff like asynchronous workflows and/or bookmarks.
You'll also want to check Microsoft.Activities.UnitTesting.