How do I mock the autofac's autogenerated delegate factories? - unit-testing

I'm struggling to get a unit test working for one of my classes. I want to inject my factory instead of the autogenerated factory the autofac resolves to. How do I register my own function as the delegate to replace the autogenerated delegate factory?
My code looks something like this is outline form:
interface IEntryImporter { ... }
class EntryImporter : IEntryImporter {
public EntryImporter(ISeries series, IMatch match, Entry.Factory entryFactory) {
:
}
:
}
interface IEntry : { ... }
class Entry : IEntry {
public delegate IEntry Factory();
public Entry() { ... }
}
interface IMatch : { ... }
class Match : IMatch { ... }
interface ISeries : { ... }
class Series : ISeries { ... }
void IEntry MyEntryFactory() {
var entry = new Mock<IEntry>();
:
return entry.Object;
}
void TestMe() {
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Entry>().As<IEntry>();
builder.RegisterType<Match>().As<IMatch>();
builder.RegisterType<Series>().As<ISeries>();
builder.RegisterType<EntryImporter>.As<IEntryImporter>();
var series = new Mock<ISeries>(MockBehavior.Strict);
builder.RegisterInstance<ISeries>(series.Object);
var match = new Mock<IMatch>(MockBehavior.Strict);
builder.RegisterInstance<IMatch>(match.Object);
// How to register MyEntryFactory as Entry.Factory for autofac to resolve?
using(var container = builder.Build()) {
var importer = container.Resolve<IEntryImporter>();
:
}
}

You can register your own method for use as the mock entry factory as follows:
builder.Register<Entry.Factory>(c => MyEntryFactory).As<Entry.Factory>();
I have got your sample working as part of Autofac Answers on GitHub.

Related

.net core xunit How verify if method was called from inherited class

I have a base class called BaseService, and i want to verify if method IsValid was called in my unit test.
public interface IBaseService
{
bool IsValid<Dto, DtoValidator>(Dto entityDto, DtoValidator validator) where DtoValidator : AbstractValidator<Dto>;
}
public class BaseService : IBaseService
{
protected readonly IMapper _mapper;
protected readonly INotificationService _notification;
public BaseService(
IMapper mapper,
INotificationService notification)
{
_mapper = mapper;
_notification = notification;
}
public virtual bool IsValid<Dto, DtoValidator>(Dto entityDto, DtoValidator validator) where DtoValidator : AbstractValidator<Dto>
{
var result = validator.Validate(entityDto);
foreach (var error in result.Errors)
{
_notification.Notify(error.ErrorMessage);
}
return result.IsValid;
}
}
Class that use BaseService , some parts of code was omited
public interface IAfiliadoService : IBaseService {}
public class AfiliadoService : BaseService, IAfiliadoService
{
public AfiliadoService(
IMapper mapper,
INotificationService notification) : base(mapper, notification)
{
_afiliadoRepository = afiliadoRepository;
_lojaRepository = lojaRepository;
}
public async Task<AfiliadoResponseDto> AddAsync(AddAfiliadoRequestDto request)
{
if (IsValid(request, new AddAfiliadoRequestDtoValidator()))
{
}
}
}
In my test project i created those classes
public class MockBaseService
{
public readonly Mock<IMapper> _mapper;
public readonly Mock<INotificationService> _notification;
public MockBaseService()
{
_mapper = new Mock<IMapper>();
_notification = new Mock<INotificationService>();
}
}
public class AfiliadoServiceTest : MockBaseService
{
private readonly IAfiliadoService _afiliadoService;
public AfiliadoServiceTest()
{
_afiliadoService = new AfiliadoService(
_mapper.Object,
_notification.Object);
}
[Fact]
public async Task AdicionarUsuarioComEmailQueJaExisteDeveNotificar()
{
var request = new AddAfiliadoRequestDto();
var result = await _afiliadoService.AddAsync(request);
Assert.Null(result);
_notification
.Verify(v => v.Notify(It.IsAny<string>()), Times.Once);
// Here i want verify if method IsValid was called Once, like the verification above
}
}
I tried some things but with no success.
Exemple with what i want.
var mock = new Mock<AfiliadoService>();
mock.Verify(v => v.IsValid(request, new AddAfiliadoRequestDtoValidator()), Times.Once);
var mock = new Mock<AfiliadoService>(_mapper.Object,
_notification.Object);
var result = await mock.Object.AddAsync(request);
mock.Verify(v => v.IsValid(request, new AddAfiliadoRequestDtoValidator()), Times.Once);
This last one i got the message
Message:
Moq.MockException :
Expected invocation on the mock once, but was 0 times: v => v.IsValid<AddAfiliadoRequestDto, AddAfiliadoRequestDtoValidator>(AddAfiliadoRequestDto, AddAfiliadoRequestDtoValidator)
Performed invocations:
Mock<AfiliadoService:1> (v):
BaseService.IsValid<AddAfiliadoRequestDto, AddAfiliadoRequestDtoValidator>(AddAfiliadoRequestDto, AddAfiliadoRequestDtoValidator)
What im doing wrong?
Im using .net core - 3.1
xunit - 2.4.1
Moq - 4.16.0

Modify InstalledUICulture in c#

Is there a way to change InstalledUICulture from English to Germany in test?
var groups = new ObservableDictionary<string, IGroupViewModel>(vm =>
vm.Name.ToString(CultureInfo.InstalledUICulture));
var isGroupExists = groups.ContainsKey(GroupName.ToString(CultureInfo.InstalledUICulture));
if (!isGroupExists)
{
groups.Add(new GroupViewModel());
}
Can you please give me some example?
Something like this. Instead of coupling your code directly to CultureInfo.InstalledUICulture you use a layer of indirection to allow you to pretend that the current UI culture is whatever you want.
I don't know your classes or how you are creating services, but I've assumed some sort of DI and used constructor parameters for the provider (or service or whatever you want to call it)
// App code
public interface ICurrentCultureProvider {
CultureInfo CurrentInstalledUICulture { get; }
}
public class CurrentCultureProvider : ICurrentCultureProvider {
public CultureInfo CurrentInstalledUICulture => CultureInfo.InstalledUICulture;
}
public class SUT {
private readonly ICurrentCultureProvider cultureProvider;
public SUT(ICurrentCultureProvider cultureProvider) {
this.cultureProvider = cultureProvider;
}
public object Method(??? vm) {
var currentUICulture = cultureProvider.CurrentInstalledUICulture;
var groups = new ObservableDictionary<string, IGroupViewModel>(vm => vm.Name.ToString(currentUICulture));
var isGroupExists = groups.ContainsKey(GroupName.ToString(currentUICulture));
if (!isGroupExists) {
groups.Add(new GroupViewModel());
}
return groups;
}
}
// Test code. Could make this return any culture by using a parameter.
public class GermanCultureProvider : ICurrentCultureProvider {
public CultureInfo CurrentInstalledUICulture => new CultureInfo("de-DE");
}
[TestFixture]
public class Sample_Test {
[Test]
public void Demo() {
var sut = new SUT(new GermanCultureProvider());
var vm = new ???();
var groups = sut.Method(vm);
// Assert correct in German etc
}
}

repository get an instance of a context from a bootstrap container

the repository is a prop of an Mvc controller, i'm trying to write a test method to check this controller,
but i get an error in the container call...
i'm new in mvc and testing.. so i dont know where to start
how can i do this?
this is how the test looks like:
public void SomeTest()
{
var controller= new SomeController();
var result = SomeController.Index();
Assert.IsNotNull(result);
}
The error i recive when i run the test
an exception of type System.NullReferenceException occurred in SomeContext.dll but was not handled in user code
Has your repository been initialized?
In your controller:
private Repository Repository {get;set;}
public ActionResult Index()
{
Repository = new Repository();
var something = Repository.DoSomeWork();
return View(something);
}
In your test class:
public void SomeTest()
{
var controller = new SomeController();
var result = controller.Index();
Assert.IsNotNull(result);
}
or if you are using dependency injection, with Ninject property injection you can try using Moq to inject the class:
public class SomeController : Controller
{
private IRepository repository;
[Inject]
public IRepository Repository
{
get { return repository; }
set { repository = value; }
}
// GET: /Some/
public ActionResult Index()
{
var someCollection = Repository.SomeMethod("some parameter");
foreach (var value in someCollection)
{
ViewData["message"] += value;
}
return View(someCollection);
}
}
and the test class with moq:
public class SomeTestClass
{
private Mock<IRepository> mockRepository;
[Test]
public void GivenSometestThenExpectSomeResult()
{
// Arrange
var controller = new SomeController();
mockRepository = new Mock<IRepository>();
mockRepository.Setup(x => x.SomeMethod(It.IsAny<string>())).Returns(new List<string>());
controller.Repository = mockRepository.Object;
// Act
ActionResult result = controller.Index();
// Assert
Assert.AreEqual("Index", result.ViewName);
}
}

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.

Unit Test a CSLA Asynchronous Validation Rule

I have a validation rule on a CSLA Business Base stereotyped class. I'm having trouble figuring out how to unit test the validation rule as it includes an asynchronous callback lambda expression. Here's some example code:
using System;
using System.Collections.Generic;
using Csla;
using Csla.Validation;
namespace UnitTestCSLAAsyncValidationRule
{
public class BusinessObject : BusinessBase<BusinessObject>
{
protected static PropertyInfo<string> CodeProperty = RegisterProperty<string>(p => p.Code);
public string Code
{
get { return GetProperty(CodeProperty); }
set { SetProperty(CodeProperty, value); }
}
protected override void AddBusinessRules()
{
ValidationRules.AddRule(CodeValidator, new AsyncRuleArgs(CodeProperty));
}
public static void CodeValidator(AsyncValidationRuleContext context)
{
var code = (string) context.PropertyValues["Code"];
CodeList codeList;
CodeList.GetCodeList((o, l) =>
{
codeList = l.Object;
if (codeList.Contains(code))
{
context.OutArgs.Result = false;
context.OutArgs.Description = "Code already in use.";
}
else
{
context.OutArgs.Result = true;
}
});
context.Complete();
}
}
public class CodeList : List<string>
{
public static void GetCodeList(EventHandler<DataPortalResult<CodeList>> handler)
{
DataPortal<CodeList> dp = new DataPortal<CodeList>();
dp.FetchCompleted += handler;
dp.BeginFetch();
}
private void DataPortal_Fetch()
{
// some existing codes..
Add("123");
Add("456");
}
}
}
I would like to test this with a test similar to the following:
using NUnit.Framework;
namespace UnitTestCSLAAsyncValidationRule.Test
{
[TestFixture]
public class BusinessObjectTest
{
[Test]
public void CodeValidationTest()
{
var bo = new BusinessObject();
bo.Code = "123";
Assert.IsNotEmpty(bo.BrokenRulesCollection);
}
}
}
However, the test Assert runs before the async callback. Is this something UnitDriven could help with? I've had a look at it but can't see how to use it in this scenario.
Thanks,
Tom
Answered by JonnyBee on http://forums.lhotka.net/forums/p/10023/47030.aspx#47030:
using NUnit.Framework;
using UnitDriven;
namespace UnitTestCSLAAsyncValidationRule.Test
{
[TestFixture]
public class BusinessObjectTest : TestBase
{
[Test]
public void CodeValidationTest()
{
UnitTestContext context = GetContext();
var bo = new BusinessObject();
bo.ValidationComplete += (o, e) =>
{
context.Assert.IsFalse(bo.IsValid);
context.Assert.Success();
//Assert.IsNotEmpty(bo.BrokenRulesCollection);
};
bo.Code = "123";
context.Complete();
}
}
}
Please not there was a small bug in my validation rule method - the call to AsyncValidationRuleContext.Complete() needs to be inside the lambda.
Thanks,
Tom