variable casting error in c# - c#

public CommandModule(ICommandFetcher fetcher,ICommandBus commandBus)
{
Post["/"] = parameters =>
{
var commandRequest = this.Bind<MessageEnvelope>();
var command = fetcher.FetchFrom(commandRequest);
commandBus.Send((ICommand)command, commandRequest.MetaData);
return HttpStatusCode.OK;
};
}
error-->Unable to cast object of type 'Castle.Proxies.ObjectProxy_2' to type 'Vetserve.Messages.Shared.ICommand'.
in commandBus.Send((ICommand)command, commandRequest.MetaData); line
Hi
when i try to test using nunit test this method has previous error how can i fix it
this is my test class
[Test]
public void whern_reseiving_command_it_sent_to_the_command_bus()
{
var rCommand = new DummyCommand() {SomeProp = 2};
var serializedCommand = JsonConvert.SerializeObject(rCommand);
var envelope = new MessageEnvelope()
{
MetaData = new MetaData() {MessageType = "DummyCommand", MessageTypeVersion = 1},
MessageData = serializedCommand
};
var fakeCommand = A.Fake<ICommandBus>();
var fakeCxxommand = A.Fake<ICommandFetcher>();
var browser = new Browser(with =>
{
with.Module<CommandModule>();
with.Dependency<ICommandBus>(fakeCommand);
with.Dependency<ICommandFetcher>(fakeCxxommand);
});
var result = browser.Post("/", with =>
{
with.HttpRequest();
with.JsonBody(envelope);
});
A.CallTo(() => fakeCommand.Send(A<ICommand>.Ignored , envelope.MetaData)).MustHaveHappened();
// A.CallTo(() => fakeCommand.Send(A<ICommand>.Ignored, A<MetaData>._)).MustHaveHappened();
}

[Test]
public void whern_reseiving_command_it_sent_to_the_command_bus()
{
var rCommand = new DummyCommand() {SomeProp = 2};
var serializedCommand = JsonConvert.SerializeObject(rCommand);
var envelope = new MessageEnvelope()
{
MetaData = new MetaData{MessageType = "DummyCommand", MessageTypeVersion = 1},
MessageData = serializedCommand
};
var fakeCommand = A.Fake<ICommandBus>();
var fakeCommandFetcher = A.Fake<ICommandFetcher>();
A.CallTo(()=> fakeCommandFetcher.FetchFrom(A<MessageEnvelope>._)).Returns(rCommand);
var browser = new Browser(with =>
{
with.Module<CommandModule>();
with.Dependency<ICommandBus>(fakeCommand);
with.Dependency<ICommandFetcher>(fakeCommandFetcher);
});
var result = browser.Post("/", with =>
{
with.HttpRequest();
with.JsonBody(envelope);
});
A.CallTo(() => fakeCommand.Send(rCommand,A<MetaData>.That.Matches(m =>m.ContextInfo == envelope.MetaData.ContextInfo && m.MessageType == envelope.MetaData.MessageType))).MustHaveHappened();
}
this is my new test method it work fine.
previous error occur due to wrong type of fetch from method
public interface ICommandFetcher
{
Object FetchFrom(MessageEnvelope messageEnvelope);
}
i changed it into
public interface ICommandFetcher
{
ICommand FetchFrom(MessageEnvelope messageEnvelope);
}
now its working.

Related

Unable to cast object of type 'System.Linq.EnumerableQuery` to type 'MongoDB.Driver.Linq.IMongoQueryable`

I have a class SendNotificationsToSubscribersCommandHandler with the following Method Handle and I have test method GetAllSubscriptionsWithCorrectParamsProductId() to check that Handle method returns correct List.
I get following error:
Message:
Test method Grand.Services.Tests.Commands.Handlers.Catalog.SendNotificationsToSubscribersCommandHandlerTest.GetAllSubscriptionsWithCorrectParamsProductId threw exception:
System.InvalidCastException: Unable to cast object of type 'System.Linq.EnumerableQuery`1[Grand.Domain.Catalog.BackInStockSubscription]' to type 'MongoDB.Driver.Linq.IMongoQueryable`1[Grand.Domain.Catalog.BackInStockSubscription]'.
Stack Trace:
MongoQueryable.Where[TSource](IMongoQueryable`1 source, Expression`1 predicate)
SendNotificationsToSubscribersCommandHandler
public class SendNotificationsToSubscribersCommandHandler : IRequestHandler<SendNotificationsToSubscribersCommand, IList<BackInStockSubscription>>
{
private readonly ICustomerService _customerService;
private readonly IWorkflowMessageService _workflowMessageService;
private readonly IRepository<BackInStockSubscription> _backInStockSubscriptionRepository;
public SendNotificationsToSubscribersCommandHandler(
ICustomerService customerService,
IWorkflowMessageService workflowMessageService,
IRepository<BackInStockSubscription> backInStockSubscriptionRepository)
{
_customerService = customerService;
_workflowMessageService = workflowMessageService;
_backInStockSubscriptionRepository = backInStockSubscriptionRepository;
}
public async Task<IList<BackInStockSubscription>> Handle(SendNotificationsToSubscribersCommand request, CancellationToken cancellationToken)
{
if (request.Product == null)
throw new ArgumentNullException("product");
int result = 0;
var query = _backInStockSubscriptionRepository.Table;
//product
query = query.Where(biss => biss.ProductId == request.Product.Id);
//warehouse
if (!string.IsNullOrEmpty(request.Warehouse))
query = query.Where(biss => biss.WarehouseId == request.Warehouse);
//warehouse
if (!string.IsNullOrEmpty(request.AttributeXml))
query = query.Where(biss => biss.AttributeXml == request.AttributeXml);
query = query.OrderByDescending(biss => biss.CreatedOnUtc);
var subscriptions = await query.ToListAsync();
//var subscriptions = await GetAllSubscriptionsByProductId(request.Product.Id, request.AttributeXml, request.Warehouse);
foreach (var subscription in subscriptions)
{
var customer = await _customerService.GetCustomerById(subscription.CustomerId);
//ensure that customer is registered (simple and fast way)
if (customer != null && CommonHelper.IsValidEmail(customer.Email))
{
var customerLanguageId = customer.GetAttributeFromEntity<string>(SystemCustomerAttributeNames.LanguageId, subscription.StoreId);
await _workflowMessageService.SendBackInStockNotification(customer, request.Product, subscription, customerLanguageId);
result++;
}
}
return subscriptions;
}
}
My test method:
[TestClass()]
public class SendNotificationsToSubscribersCommandHandlerTest
{
private Mock<ICustomerService> _mockCustomerService;
private Mock<IRepository<BackInStockSubscription>> _mockBackInStockSubscriptionRepository;
private Mock<IMongoQueryable<BackInStockSubscription>> _mongoQueryableMock;
private IQueryable<BackInStockSubscription> _expectedQueryable;
private List<BackInStockSubscription> _expected;
private Mock<IWorkflowMessageService> _mockWorkflowMessageService;
private SendNotificationsToSubscribersCommandHandler _handler;
private SendNotificationsToSubscribersCommand _sendNotificationsToSubscribersCommand;
[TestInitialize()]
public void Init()
{
_expected = new List<BackInStockSubscription>
{
new BackInStockSubscription { WarehouseId = "11", ProductId = "11" },
new BackInStockSubscription { WarehouseId = "11", ProductId = "11" }
};
_mockCustomerService = new Mock<ICustomerService>();
_mockBackInStockSubscriptionRepository = new Mock<IRepository<BackInStockSubscription>>();
_expectedQueryable = _expected.AsQueryable();
_mongoQueryableMock = new Mock<IMongoQueryable<BackInStockSubscription>>();
_mongoQueryableMock.As<IEnumerable<BackInStockSubscription>>();
_mongoQueryableMock.Setup(x => x.ElementType).Returns(_expectedQueryable.ElementType);
_mongoQueryableMock.Setup(x => x.Expression).Returns(_expectedQueryable.Expression);
_mongoQueryableMock.Setup(x => x.Provider).Returns(_expectedQueryable.Provider);
_mongoQueryableMock.Setup(x => x.GetEnumerator()).Returns(_expectedQueryable.GetEnumerator());
_mockBackInStockSubscriptionRepository.Setup(x => x.Table).Returns(_mongoQueryableMock.Object);
_mockWorkflowMessageService = new Mock<IWorkflowMessageService>();
_sendNotificationsToSubscribersCommand = new SendNotificationsToSubscribersCommand { Product = new Product { Id = "11"}, Warehouse = "11" };
_handler = new SendNotificationsToSubscribersCommandHandler(_mockCustomerService.Object, _mockWorkflowMessageService.Object, _mockBackInStockSubscriptionRepository.Object);
}
[TestMethod()]
public async Task GetAllSubscriptionsWithCorrectParamsProductId()
{
var result = await _handler.Handle(_sendNotificationsToSubscribersCommand, default);
var resultList = result.ToList();
Assert.AreEqual(resultList, _expected);
}
}
I get error on line
query = query.Where(biss => biss.ProductId == productId);
UPDATE
When I debug application, property _backInStockSubscriptionRepository.Table has Expression.Value = {aggregate([])}
If I debug test method property Table of Mock object has Expression.Value with Value = System.Collections.Generic.List<Grand.Domain.Catalog.BackInStockSubscription> with my two objects.
Any help is greatly appreciated
Take a look at here: How to mock a class that implements multiple interfaces
Try something like this:
_mongoQueryableMock = new Mock<IMongoQueryable<BackInStockSubscription>>();
_mongoQueryableMock.As<IEnumerable<BackInStockSubscription>>();
...

Setup Mock for Update function (CRUD)

I try to Setup a mock for Update function,
public class JelentkezokService : IJelentkezokService
{
IJelentkezokRepository JelentkezokRepository { get; set; }
public Jelentkezok Update(Jelentkezok jelentkezo)
{
if (JelentkezokRepository.GetAll().Any(x => x.Id == jelentkezo.Id))
{
return JelentkezokRepository.Update(jelentkezo);
}
//The ID is not exist
else throw new Exception($"A megadott jelentkező ID nem létezik: {jelentkezo.Id}");
}
}
testing whether the function was called but it goes for the exception in the Service. Any idea?
[TestFixture]
public class JelentkezokBLTests
{
Mock<IJelentkezokRepository> JelentkezokRepositoryMock;
[Test]
public void JelentkezokUpdateMeghivva()
{
//Arrange
JelentkezokRepositoryMock = new Mock<IJelentkezokRepository>();
var input = new DA.Jelentkezok()
{
Id = 13,
Nev = "Kis Béla",
Varos = "Győr",
Utca = "Kodály Zoltán u. 15.",
SzuletesiDatum = new DateTime(1982, 11, 19),
Iranyitoszam = 9030,
Ferfi = true,
};
var mockedResult = new DA.Jelentkezok()
{
Id = 13,
Nev = "Kis Anita",
Varos = "Győr",
Utca = "Kodály Zoltán u. 15.",
SzuletesiDatum = new DateTime(1982, 11, 19),
Iranyitoszam = 9030,
Ferfi = false,
};
JelentkezokRepositoryMock.Setup(x => x.Update(input)).Returns(mockedResult);
JelentkezokService service = new JelentkezokService(JelentkezokRepositoryMock.Object);
//Act
var updateJelentkezo = service.Update(input);
//Assert
//Assert.That(input, Is.Not.Null);
JelentkezokRepositoryMock.Verify(v => v.Update(input), Times.AtLeastOnce);
}
I have the error
Message: System.Exception : A megadott jelentkező ID nem létezik: 13 //The ID is not exist.
Looks like JelentkezokRepository.GetAll() is not behaving as expected.
Assuming it returns a collection
IEnumerable<Jelentkezok> GetAll();
That may need to be setup as well.
//...
var item = new DA.Jelentkezok() {
Id = 13,
};
var all = new [] { item };
JelentkezokRepositoryMock.Setup(x => x.GetAll()).Returns(all);
//...
In order to allow the if condition to flow as expected when the test is exercised.

Moq: How to mock method with `complex type` parameter

Original title:
Moq: Mocking method method with out parameter returns empty array
The problem was not with the out parameter but with the complex type parameter albumFilters of complex type AlbumFilter. See my Answer for details.
I have Moq working for a method without an out parameter but when I try and Moq with an out parameter it returns an empty array.
The GetAllAlbums_ok_returnsdata_test() passes. The GetAllAlbumsPaged_test() fails. The call to the _inventoryService in the GetAllAlbumsPaged method in the AlbumApiController returns an empty array Album[].
I've looked at the Moq Quickstart section on using out arguments.
// out arguments
var outString = "ack";
// TryParse will return true, and the out argument will return "ack",
lazy evaluated
mock.Setup(foo => foo.TryParse("ping", out outString)).Returns(true);
Test Class:
[Fact]
public void GetAllAlbums_ok_returnsdata_test() {
Mock<IInventoryService> mockInventoryService
= new Mock<IInventoryService>();
Album[] albums = { new Album { AlbumId = 1 },
new Album { AlbumId = 2 } };
mockInventoryService.Setup(obj => obj.GetAllAlbums()).Returns(albums);
AlbumApiController controller = new AlbumApiController(mockInventoryService.Object);
IHttpActionResult response = controller.GetAllAlbums();
var contentResult = response as OkNegotiatedContentResult<Album[]>;
Assert.NotNull(contentResult);
Assert.NotNull(contentResult.Content);
var data = contentResult.Content;
Assert.Equal(data, albums); }
[Fact]
public void GetAllAlbumsPaged_test() {
Mock<IInventoryService> mockInventoryService
= new Mock<IInventoryService>();
Album[] albums = new Album[20];
for (int i = 0; i < 20; i++) albums[i] = new Album { AlbumId = i + 1 };
var albumFilter = new AlbumFilter { AlbumNumber = "", Artist = "",
Title = "", Genre = 0, Price = 0, StockAmount = 0 };
var sortItems = new List<SortItem>();
int totalCount;
mockInventoryService.Setup(obj => obj.GetAllAlbumsPaged(out totalCount, albumFilter,
sortItems, 0, 4)).Returns(albums);
AlbumApiController controller = new AlbumApiController(mockInventoryService.Object);
IHttpActionResult response = controller.GetAllAlbumsPaged(Json.Encode(albumFilter),
Json.Encode(sortItems), 0, 4);
var contentResult = response as OkNegotiatedContentResult<object>;
Assert.NotNull(contentResult); }
AlbumApiController:
public class AlbumApiController : ApiController
{
private readonly IInventoryService _inventoryService;
public AlbumApiController(IInventoryService inventoryService)
{ _inventoryService = inventoryService; }
[HttpGet]
[Route("getallalbums")]
public IHttpActionResult GetAllAlbums() {
return GetHttpResponse(Request, () => {
var albums = _inventoryService.GetAllAlbums();
return Ok(albums); }); }
[HttpGet]
[Route("getallalbumspaged/{pageIndex}/{pageSize}")]
public IHttpActionResult GetAllAlbumsPaged(string filters, string sorts,
int pageIndex, int pageSize) {
var _filters = JsonConvert.DeserializeObject<AlbumFilter>(filters);
var _sorts = JsonConvert.DeserializeObject<List<SortItem>>(sorts);
return GetHttpResponse(Request, () => {
int totalCount;
var albums = _inventoryService.GetAllAlbumsPaged(out totalCount, _filters,
_sorts, pageIndex, pageSize);
var albums_Count = new { albums, totalCount };
return Ok(albums_Count); }); } }
Update:
I added this test method to the AlbumAPIController:
[HttpGet]
public IHttpActionResult GetTest(int intTest)
{
return GetHttpResponse(Request, () => {
int testInt;
var albums = _inventoryService.GetTest(out testInt, intTest);
return Ok(albums);
});
}
and this test to the test class:
[Fact]
public void GetTest_test() {
Mock<IInventoryService> mockInventoryService
= new Mock<IInventoryService>();
Album[] albums = new Album[20];
for (int i = 0; i < 20; i++) albums[i] = new Album { AlbumId = i + 1 };
int testInt = 15;
mockInventoryService.Setup(obj => obj.GetTest(out testInt, 5)).Returns(albums);
AlbumApiController controller = new AlbumApiController(mockInventoryService.Object);
IHttpActionResult response = controller.GetTest(5);
var contentResult = response as OkNegotiatedContentResult<Album[]>;
Assert.NotNull(contentResult);
Assert.NotNull(contentResult.Content);
var data = contentResult.Content;
Assert.Equal(data, albums); }
The test passed and the testInt was updated in the GetTest method so the problem doesn't seem to be with the 'out parameter`.
Per Diana's troubleshooting suggestion I added this to the GetAllAlbumsPaged method (right after the JsonConverts) to ensure the issue wasn't with the JSON.
_filters = new AlbumFilter { AlbumNumber = "", Artist = "",
Title = "", Genre = 0, Price = 0, StockAmount = 0 };
_sorts = new List<SortItem>();
The call to the _inventoryService.GetAllAlbumsPaged method still returns an empty array, Albums[].
The out parameter was not the problem. The complex type parameter AlbumFilter was the problem. Moq apparently didn't like the complex type. I was able to get it to work by changing the mockInventoryService setup by passing It.IsAny<AlbumFilter>() instead of the instance of the AlbumFilter, albumFilter.
mockInventoryService.Setup(obj => obj.GetAllAlbumsPaged(out totalCount,
It.IsAny<AlbumFilter>(), sortItems, 0, 4)).Returns(albums);

Moq calls original internal method in spite of Setup

Hello,
I'm having trouble getting my class to call a Moq'd method. My situation is thus:
public class ResetPasswordsTask : IRefreshTimeTask
{
public long ExecutionId => 2100;
public bool Enabled => true;
public Dictionary<string, object> Params { get; set; }
public KeyValuePair<string, Type>[] RequiredParams => new[]
{
new KeyValuePair<string, Type>("targetConfigs", typeof(InMemoryConfiguration))
};
public ILogger Logger { get; set; }
internal IConfiguration SandboxConfig;
internal IPartnerService PartnerService;
internal ISalesForceBulkDataInserter DataInserter;
public void Execute()
{
SandboxConfig = (IConfiguration)Params["targetConfigs"];
PartnerService = Login.SalesforceApiLogin(true, SandboxConfig);
DataInserter = new SalesForceBulkDataInserter();
//InitialiseImapClient();
// Retrieve users
var users = TestAutomation.Salesforce.Pages.Base.User.GetUsers(PartnerService, SandboxConfig.Refresh_Usernames);
// Upsert emails
var emailUpsertResults = UpsertEmails(users, SandboxConfig.IMAP_Email);
// Hit mailbox and visit confirmation links
var activatedUsers = emailUpsertResults.Values.Where(r => r.Status == EmailResetStatusEnum.Success).Select(r => r.User).ToList();
var confirmationLinkResults = ConfirmEmailChanges(activatedUsers);
// Upsert passwords
// All the users, except those for whom email update failed
var passwordUpdateUsers = users.Except(confirmationLinkResults.Values.Where(r => !r.Success).Select(r => r.User)).ToList();
var passwordUpsertResults = UpsertPasswords(passwordUpdateUsers);
// Hit mailbox for new tokens
var completeResetResults = RetrieveTokens(passwordUpsertResults.Values.Where(r => r.Success));
var output = string.Join("\n", completeResetResults.Values.Where(c => c.Success).Select(result => string.Join("\t", new List<string> { result.User.Username, result.Password, result.SecurityToken })));
//Logger.Info(output);
Logger.Info(System.IO.Path.GetDirectoryName("."));
Logger.Info(System.Reflection.Assembly.GetExecutingAssembly().Location);
OpenSslEncryption.EncryptToFile(SandboxConfig.EncryptionPassword, "passwords.enc", output);
}
// Results are keyed by username
internal IDictionary<string, EmailResetResult> UpsertEmails(ICollection<User> users, string newEmail)
{
var results = users.ToDictionary(u => u.Username, u => new EmailResetResult(u));
Logger.Info($"Updating emails for {users.Count} users");
foreach (var user in users)
{
Logger.Info($"updating email for {user.Username} users");
var result = results[user.Username];
// Prevent upserting the profile
if (user.ProfileId != null)
{
Logger.Info("Preventing profile upsert");
user.ProfileId.SalesForceId = user.ProfileId.OriginId;
}
// If the user has had their email set to what we're setting now, they can be skipped
if (user.Email.Equals(newEmail, StringComparison.InvariantCultureIgnoreCase) && user.IsActive)
{
Logger.Info($"User {user.Username} has their email set to {newEmail}; skipping");
result.Status = EmailResetStatusEnum.Skipped;
continue;
}
// Otherwise, set the email and carry on
user.Email = newEmail;
user.IsActive = true;
// dataInserter.Upsert won't produce errors individually, and instead only log faulty upserts
try
{
DataInserter.Upsert(new List<User> { user });
Logger.Info($"Activated user {user.Username}");
result.Status = EmailResetStatusEnum.Success;
}
catch (Exception e)
{
var error = $"Failed to update the email for user {user.Username} to {newEmail}. Error details: {e}";
Logger.Error(TestAutomation.Framework.Core.Logger.Logger.FormatJson(error));
result.ErrorMessage = e.ToString();
result.Status = EmailResetStatusEnum.Failure;
}
}
return results;
}
internal IDictionary<string, Result> ConfirmEmailChanges(ICollection<User> users)
{
var results = users.ToDictionary(u => u.Username, u => new Result(u));
// Ran as a task to have a timeout
Task.Run(() => ConfirmEmailChangesTask(results, users)).Wait(TimeSpan.FromMinutes(users.Count * 5));
return results;
}
internal void ConfirmEmailChangesTask(IDictionary<string, Result> results, ICollection<User> users)
{
var remainingUsers = new HashSet<User>(users);
while (true)
{
// Wait a bit; either for the emails to come in, or to give the webserver breathing room
Thread.Sleep(new TimeSpan(0, 0, 15));
Logger.Info($"Opening mailbox for {SandboxConfig.IMAP_Email}");
using (var imapClient = CreateImapClient())
{
var messages = imapClient.SearchMessages(SearchQuery.NotSeen.And(SearchQuery.DeliveredAfter(DateTime.Now.AddHours(-1))));
Logger.Info($"Found {messages.Count} messages");
var remainingUsersCopy = new HashSet<User>(remainingUsers);
Logger.Info($"Attempting to confirm emails for {remainingUsers.Count} users");
foreach (var user in remainingUsersCopy)
{
Logger.Info("Attempting to confirm email change for " + user.Username);
foreach (var message in messages.Where(m => m.MimeMessage.TextBody.Contains(user.Username) && m.MimeMessage.Subject.Contains("Sandbox: Finish changing your Salesforce")))
{
Logger.Info("Message found");
var confirmLink = GetEmailConfirmationLink(message);
if (confirmLink == null) continue;
// Visit the URL
var request = WebRequest.Create(confirmLink);
request.Timeout = (int)TimeSpan.FromSeconds(20).TotalMilliseconds;
var result = results[user.Username];
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
var statusCode = response.StatusCode;
if (statusCode != HttpStatusCode.OK)
{
var error = $"Failed to load the email change confirmation link: {confirmLink}. HTTP Response: ({statusCode})";
Logger.Error(TestAutomation.Framework.Core.Logger.Logger.FormatJson(error));
result.Success = false;
result.ErrorMessage = error;
}
}
}
catch (WebException e)
{
Logger.Error($"Request failed: {e.Message}\nWill retry later");
continue;
}
result.Success = true;
remainingUsers.Remove(user);
imapClient.MarkAsRead(message);
//Break down mailbox checks
Thread.Sleep(new TimeSpan(0, 0, 1));
}
}
}
if (!remainingUsers.Any())
break;
}
}
#region MailboxInteraction
internal static string GetEmailConfirmationLink(Message message)
{
// Extract confirmation URL
var confirmLinkMatch = Regex.Match(message.MimeMessage.TextBody, #"([a-z]+:\/\/.*\.salesforce\.com\/\S*)");
return !confirmLinkMatch.Success ? null : confirmLinkMatch.Groups[1].Value;
}
internal static string GetSecurityToken(Message message)
{
var tokenMatch = Regex.Match(message.MimeMessage.TextBody, #"Security token \(case-sensitive\): (?<token>\w+)");
return !tokenMatch.Success ? null : tokenMatch.Groups[1].Value;
}
internal virtual IMailClient CreateImapClient()
{
return new IMAPClient(SandboxConfig.IMAP_Username, SandboxConfig.IMAP_Password, SandboxConfig.IMAP_URL);
}
#endregion
}
Test class:
[TestFixture]
public class WhenResettingUserPasswords
{
private const string ConfirmationLink = "test://testdomain.salesforce.com/test/";
[OneTimeSetUp]
public void WebRequestSetup()
{
WebRequest.RegisterPrefix("test", TestableWebRequestCreateFactory.GetFactory());
var uri = new Uri("test://testdomain.salesforce.com/test/");
var expectedRequest = new TestableWebRequest(uri);
expectedRequest.EnqueueResponse(HttpStatusCode.OK, "Success", "Even more success!", false);
TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRequest);
}
private static SetupBag Setup()
{
var bag = new SetupBag
{
Logger = new InMemoryLogger(),
EmailConfirmationLink = ConfirmationLink,
SecurityToken = "TheSecurityToken",
Environment = "EnvName",
EnvironmentUrl = "http://aaa.bbb.ccc/",
User = new User
{
IsActive = false,
Username = "joe.bloggs#company.com",
Email = "joe.bloggs=company.com#example.com",
OriginId = "ABCDEFGHIJKLMNO"
}
};
var task = new Mock<Tasks.ResetPasswordsTask>(MockBehavior.Strict) { CallBase = true };
task.Object.Logger = bag.Logger;
var confirmMessage = new Message
{
UID = new UniqueId(0),
MimeMessage = new MimeMessage
{
Subject = "Sandbox: Finish changing your Salesforce",
Body = new TextPart("plain") { Text = "Confirm email change for joe.bloggs#company.com: " + bag.EmailConfirmationLink }
}
};
var tokenMessage = new Message
{
UID = new UniqueId(1),
MimeMessage = new MimeMessage
{
Subject = "Sandbox: Your new Salesforce security token",
Body = new TextPart("plain") { Text = "New security token for joe.bloggs#company.com: " + bag.SecurityToken }
}
};
var mailClientMock = new Mock<IMailClient>(MockBehavior.Strict);
mailClientMock.Setup(m => m.SearchMessages(It.IsAny<SearchQuery>())).Returns(new List<Message> { confirmMessage, tokenMessage });
task.Setup(t => t.CreateImapClient()).Returns(() => mailClientMock.Object);
var dataInserterMock = new Mock<ISalesForceBulkDataInserter>();
dataInserterMock.Setup(m => m.Upsert(It.IsAny<List<User>>(), false));
var config = new InMemoryConfiguration
{
IMAP_Email = "test.email#company.com"
};
task.Object.SandboxConfig = config;
bag.Task = task;
return bag;
}
[Test]
public void UpsertEmailsTest()
{
var bag = Setup();
var task = bag.Task;
var output = task.Object.ConfirmEmailChanges(new[] { bag.User });
Assert.IsTrue(output.ContainsKey(bag.User.Username));
Assert.IsTrue(output[bag.User.Username].Success);
Assert.IsEmpty(output[bag.User.Username].ErrorMessage);
Assert.AreEqual(task.Object.SandboxConfig.IMAP_Email, output[bag.User.Username].User.Username);
}
}
Now, the result is that calling task.Object.ConfirmEmailChanges() raises an exception about arguments to new IMAPClient() being null, which should not have been called at all. I could not find anything obviously wrong, but that might just be because I'm not familiar enough with Moq or the way my codebase does testing.
Yes, I know I'm mocking a class I want to test. I know it's a bad idea, and I'm aiming for a redesign. I cannot inject IMailClient as a dependency because it needs to be instantiated anew frequently. I have also seen this sort of technique used in our codebase, and it seemed to work.
If you are mocking a concrete class and not an interface then you must make the method you want to mock virtual.
Edit: in your new code the method is also marked as internal. See this question.
You need to declare your method as virtual or Moq is unable to override it. C# is not like Java - only members that are specifically marked are able to be overridden.
EDIT
The code you've posted should work - here is a Linqpad MVCE I generated based on your code, demonstrating that it works correctly. Therefore, you will need to post your actual code, as it has a bug in it.
void Main()
{
// Arrange
var foo = new Mock<Foo> { CallBase = true };
var bar = new Mock<IBar>();
bar.Setup(b => b.Value).Returns(2);
// setup an IBar mock
foo.Setup(f => f.CreateBar()).Returns(bar.Object);
// Act
var results = foo.Object.DoStuff();
results.Dump(); // Prints "2"
}
public class Foo
{
public int DoStuff()
{
var bar = CreateBar();
return bar.Value;
}
public virtual IBar CreateBar()
{
return new RealBar();
}
}
public interface IBar
{
int Value { get;}
}
public class RealBar : IBar
{
public int Value
{
get { return 1; }
}
}

how to generic Automapper Config

I use Automapper version 4.2.0 and I all Action Methods I have setting Like this :
var attributeGroups = _attributeGroupService.AttributeGroupDropdown();
var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<AttributeGroup, AttributeGroupViewModel>());
var mapper = mapconfiguration.CreateMapper();
var result = mapper.Map(attributeGroups, new List<AttributeGroupViewModel>());
I dont repeat this codes in all actions , I want create a generic method and just pass data to it and map it ,to do this , I create a Method like this ?
public N mapping<T,K,M,N>(T resource, K destination,M model,N newModel)
{
var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<T, K>());
var mapper = mapconfiguration.CreateMapper();
var result = mapper.Map<M,N>(model, newModel);
return result;
}
and call it like this :
var ResultTest=mapping<AttributeGroup,AttributeGroupViewModel,attributeGroups,new List<AttributeGroupViewModel>()>();
but it doesnt complie .
how can I do it?
Short answer: you need to provide types in the generic parameter list and variables in the argument list of your function call. Also, you don't need the T resource, K destination arguments at all, since they are unused.
There is another problem with your approach, since using it is not really convenient. So I suggest that you provide two specialized methods with reduced complexity.
See the below complete example. It contains the method mapAnything<...>, which is a working equivalent to your mapping<...> method. The methods mapObject<...> and mapCollection<...> are the specialized methods I was talking about.
class TestResource
{
public int Testnumber { get; set; }
public string Testtext { get; set; }
}
class TestDestination
{
public string Testtext { get; set; }
}
class Program
{
// equivalent to what you tried to do - needs explicit generic parameters on call
static N mapAnything<T, K, M, N>(M model, N newModel)
{
var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<T, K>());
var mapper = mapconfiguration.CreateMapper();
var result = mapper.Map<M, N>(model, newModel);
return result;
}
// variant for object mapping, where generics can be implicitely inferred
static N mapObject<M, N>(M model, N newModel)
{
var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<M, N>());
var mapper = mapconfiguration.CreateMapper();
var result = mapper.Map<M, N>(model, newModel);
return result;
}
// variant for lists, where generics can be implicitely inferred
static ICollection<N> mapCollection<M, N>(IEnumerable<M> model, ICollection<N> newModel)
{
var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<M, N>());
var mapper = mapconfiguration.CreateMapper();
var result = mapper.Map<IEnumerable<M>, ICollection<N>>(model, newModel);
return result;
}
static void Main(string[] args)
{
var res1 = new TestResource() { Testnumber = 1, Testtext = "a" };
var res2 = new List<TestResource>();
for (int i = 0; i < 10; i++)
{
res2.Add(new TestResource() { Testnumber = i, Testtext = "test: " + i });
}
var mapped1 = mapObject(res1, new TestDestination());
var mapped2 = mapCollection(res2, new HashSet<TestDestination>());
var mapped3 = mapAnything<TestResource, TestDestination, TestResource, TestDestination>(res1, new TestDestination());
var mapped4 = mapAnything<TestResource, TestDestination, IEnumerable<TestResource>, List<TestDestination>>(res2, new List<TestDestination>());
}
}

Categories