Invalid Argument in Method when pulling from repository - c#

I am trying to learn how this Repository works by disecting it. I am really lost so was hoping the community would help me out a bit. Please keep in mind I am new to MVC so don't tear me apart to much. The error I am getting is because I have invalid arguments. I think it is from my 3rd argument but I am not quite sure how to fix it.
ResponentRepository.GetRespondents() is the problem Notice below.
In my controller I have:
List<int> projectIdsToInclude = new List<int>();
projectIdsToInclude.Add(4);
List<int> statusesToInclude = new List<int>();
statusesToInclude.Add(1);
List<string> fieldsToInclude = new List<string>();
fieldsToInclude.Add("firstName");
IEnumerable<int> pID = projectIdsToInclude;
IEnumerable<string> fields = fieldsToInclude;
var respondents = RespondentRepository.GetRespondents(UserSession, pID, statusesToInclude, fields);
In the Respository it has:
public List<Respondent> GetRespondents(UserSessionData sessionData, IEnumerable<int> projectIdsToInclude, IEnumerable<RespondentStatus> statusesToInclude, IEnumerable<string> fieldsToInclude)
{
var request = new RespondentRequest
{
Options = new RequestOptions
{
Include = fieldsToInclude,
//OrderBy = new List<OrderBy> { new OrderBy { Direction = OrderByDirection.Descending, Field = Create.Name<Respondent>(r => r.LastActionDate) } },
Filter = new LogicExpression
{
ExpressionA = new InExpression<int>
{
Field = Create.Name<Respondent>(r => r.ProjectId),
Values = projectIdsToInclude.ToList()
},
ExpressionB = new InExpression<RespondentStatus>
{
Field = Create.Name<Respondent>(r => r.RecruitingStatus),
Values = statusesToInclude.ToList()
},
Operator = SqlOperator.And
},
}
};
return Get(request, sessionData).Data;
}
My Invalid Argument I think is coming from the argument that is IEnumerable. So when I follow RespondentStatus I see this:
public enum RespondentStatus : int
{
[Description("Not Contacted")]
NotContacted = 0,
[Description("Pre-Screened")]
PreScreened = 1,
[Description("On Hold")]
Hold = 2,
[Description("Initial Refusal")]
InitialRefusal = 3,
[Description("Qualified Refusal")]
QualifiedRefusal = 4,
[Description("Remove From Panel")]
RemoveFromPanel = 5,
Terminated = 6,
Complete = 7,
//Probably should never reuse '8' as a status since retiring "Approved" status
Approved = 8,
// Phone contact statuses
[Description("No Answer")]
NoAnswer = 30,
Busy = 31,
[Description("Left Message")]
LeftMessage = 32,
[Description("Call Back Later")]
CallBackLater = 33,
[Description("Non-working Number")]
NonWorkingNumber = 34,
}
How do I fix my code in the controller to pull respondents from this repository? I just want to return some respondents. I think if I can do that I can further dissect from there. Can someone explain what I should do to make this work or what I am missing?

statusesToInclude should be IEnumerable<RespondentStatus> You are expecting IEnumerable<RespondentStatus> in you method, but calling it with List<int>.
Either change your method signature or your calling code so that the two statusesToInclude variables match up and have the same type.
For example:
List<RespondentStatus> statusesToInclude = new List<RespondentStatus>();
statusesToInclude.Add((RespondentStatus)1);

Related

Why XUnit Test case throwing "Moq.MockException : invocation failed" error, where my inputs all are correct?

while interface mocking I am trying to send with actual inputs in model object, but getting failure with
Moq.MockException : ISearchRepo.GetEsDataWithBoolByAggregation<IndexVM>(BoolMustMatchAggregationIM) invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.
error message.
Mock method for interface input object (which is sending same like in manual)
private BoolMustMatchAggregationIM GetBoolMustMatchAggregationIMMockData()
{
var objInputs = GetTopologyTabularApplyFilterMockData();
var studentFieldValue = objInputs.StudentId != null ? string.Join(',', objInputs.StudentId) : string.Empty;
BoolMustMatchAggregationIM topoplogyApplyFilter = new BoolMustMatchAggregationIM()
{
From = objInputs.From,
Size = objInputs.Size,
IndexName = ElasticSearchIndexConstant.Index,
FirstField = DataConstant.MarketField,
FirstFieldValue = objInputs.Market,
SecondField = DataConstant.StudentField,
SecondFieldValue = studentFieldValue,
ThirdField = DataConstant.SubjectField,
ThirdFieldValue = objInputs.SubjectId != null ? objInputs.SubjectId : null,
FourthField = DataConstant.SiteIdFieldName,
FourthFieldValue = objInputs.SiteId != null ? objInputs.SiteId[0] : null,
OperatorType = DataConstant.NestAndOperator,
CardinalField = DataConstant.CardinalField,
SumName = DataConstant.SumName,
MinimumMatch = DataConstant.One
};
return topoplogyApplyFilter;
}
Mock method for output object from interface
private IEnumerable<SiteSubjectIndexVM> GetSiteSubjectIndexClassMockData()
{
List<SiteSubjectDetails> objListSiteSubject = new List<SiteSubjectDetails>();
SiteSubjectDetails objSiteSubject = new SiteSubjectDetails { SubjectId = 4002453 };
objListSiteSubject.Add(objSiteSubject);
List<SiteSubjectIndexVM> objListSiteSubjectIndexClass = new List<SiteSubjectIndexVM>();
SiteSubjectIndexVM objSiteSubjectIndexClass = new SiteSubjectIndexVM()
{
Id = 123,
StudentId = "SE123",
Longitude = -122.51m,
Latitude = 47.66m,
Region = "Selected",
SiteId = "SE03D123",
HasSubjectSites = 1,
Market = "HNK",
TimeStamp = new DateTime(2022, 08, 07, 11, 02, 51, 167),
AAVStatus = "Selected"
};
objListSiteSubjectIndexClass.Add(objSiteSubjectIndexClass);
objSiteSubjectIndexClass = new SiteSubjectIndexVM()
{
Id = 456,
SiteId = "SE04D456",
Subjects = objListSiteSubject,
StudentId = "SE456",
Latitude = 47.74m,
Longitude = -122.15m,
Market = "WGL",
TimeStamp = new DateTime(2022, 08, 07, 11, 02, 51, 167),
Region = "WEST",
HasSubjectSites = 1
};
objListSiteSubjectIndexClass.Add(objSiteSubjectIndexClass);
return objListSiteSubjectIndexClass;
}
Test Case
[Fact]
public async Task GetTabularApplyFilterAsync_WhenMarketIsNotNull_ReturnsSiteSubjectsIndexFromES()
{
//Arrange
var objRepoIM = GetBoolMustMatchAggregationIMMockData();
var objRepoVM = GetSiteSubjectIndexClassMockData().Where(x=>x.Id== 72337696).ToList();
var objIMapperVM = GetSiteSubjectIndexMockData().Where(x => x.Id == 72337696).ToList();
var objServiceIM = GetTabularApplyFilterMockData();
objServiceIM.StudentId = null; objServiceIM.SubjectId = null; objServiceIM.SiteId = null;
//Action
_mockISearchRepo.Setup(x => x.GetEsDataWithBoolByAggregationAsync<SiteSubjectIndexVM>(objRepoIM)).ReturnsAsync(objRepoVM);
_mockMapper.Setup(x => x.Map<IEnumerable<SiteSubjectIndex>>(objRepoVM)).Returns(objIMapperVM);
var subjectService = this.CreateSearchService();
var result = await subjectService.GetTabularApplyFilterAsync(objServiceIM).ConfigureAwait(false);
//Assert
Assert.NotNull(result);
Assert.Equal(result, objIMapperVM);
_mockRepository.VerifyAll();
}
by _mockIElasticSearchRepo.Setup(x => x.GetEsDataWithBoolByAggregationAsync<SiteLinkIndexVM>(It.IsAny<BoolMustMatchAggregationIM>())).ReturnsAsync(objRepoVM);
error get resolved, but why? where I have given correct input model with correct values.
The error message signals that there is no setup for the call. The following setup will be met, if the parameter is equal to the object that you created:
_mockISearchRepo.Setup(x => x.GetEsDataWithBoolByAggregationAsync<SiteSubjectIndexVM>(objRepoIM)).ReturnsAsync(objRepoVM);
Most likely, the call to GetEsDataWithBoolByAggregationAsync in the code under test does not use the exact same instance that you created in your test, but creates an instance of its own. Hence check will fail because it is not the same object and the setup is not matched.
You can work around this by defining the setup so that you check the parameters dynamically, e.g.
_mockISearchRepo
.Setup(x => x.GetEsDataWithBoolByAggregationAsync<SiteSubjectIndexVM>(It.Is<BoolMustMatchAggregationIM>(y => y.IndexName == ElasticSearchIndexConstant.Index))
.ReturnsAsync(objRepoVM);
In above sample, I have only included a very simple check for the index name. You can extend the expression to check the input more thoroughly.
By using this approach, the setup will be matched as soon as the expression returns true so this also works if the code under test creates the instance that is used as the parameter.

many to many select list data

I would like to list the data with linq by combining the tables shown in the picture
expected result
using (CrmContext db = new Models.CrmContext())
{
_result = (from ct in db.CustomerDefination
join authorizedin db.authorized
on ct.customerId equals authorized.authorized
join authorizedDefination in db.authorizedDefination
on authorized.authorizedId equals authorizedDefination .authorizedId
select new
{
///I want to list the authorities belonging to
the customer
}).ToList();
}
There may be more than one authoritative definition of a customer. How can I do this in the LINQ query?
I spent WAY too much time doing your job, #IbrahimALPSOY:
Google Translating the turkish database screenshot,
Understanding which table holds what data using more Google Translate,
Understanding the expected result - which fields come from which tables,
Writing sample classes to represent the database,
Generating sample data for testing.
I wasted 30+ minutes before even starting to write a query. Next time I won't. Next time, you prepare your question such that, all other people could just copy your code and try queries right away.
This is the preparation:
class Authorisation
{
public int AuthorisationId; // yetkiliid
public int AccessId; // unvanid
public string AuthoriserName;
}
class Access
{
public int AccessId; // unvanid
public string AccessName;
}
class Customer
{
public int CustomerId; // musterid
public string CustomerName;
}
class Event
{
public int CustomerId;
public int AuthorisationId;
}
void Main()
{
var Customers = new[] {
new Customer() { CustomerId = 1, CustomerName = "Anne" },
new Customer() { CustomerId = 2, CustomerName = "Barbara" },
};
var Accesses = new[] {
new Access() { AccessId = 1, AccessName = "Read" },
new Access() { AccessId = 2, AccessName = "Write" },
};
var Authorisations = new[] {
new Authorisation() { AuthorisationId = 1, AuthoriserName = "The boss", AccessId = 1 }, // The boss can give read rights
new Authorisation() { AuthorisationId = 2, AuthoriserName = "The boss", AccessId = 2 }, // The boss can give write rights
new Authorisation() { AuthorisationId = 3, AuthoriserName = "A rookie", AccessId = 1 }, // A new employee can only give read rights
};
var Events = new[] {
new Event() { CustomerId = 1, AuthorisationId = 3 }, // A rookie let Anne read
new Event() { CustomerId = 1, AuthorisationId = 2 }, // While the boss let Anne write and scolded rookie
new Event() { CustomerId = 2, AuthorisationId = 1 }, // The boss thinks Barbara can't be trusted with write
};
}
I used this code instead of yours, because yours:
doesn't compile,
is illegible,
is badly formatted,
skips a table you've shown on your screenshot,
contains references to contexts only you have access to.
And here are the results:
Your query becomes feasible if you start with the table with non-unique keys:
from e in Events
join c in Customers on e.CustomerId equals c.CustomerId
join a in Authorisations on e.AuthorisationId equals a.AuthorisationId
join s in Accesses on a.AccessId equals s.AccessId
select new
{
e.CustomerId,
e.AuthorisationId,
c.CustomerName,
a.AuthoriserName,
s.AccessName
}
If this is not what you needed, modify my "preparation" to fit your question.

Moq setup causing null

I'm new to Unit Testing, and Moq, so if I'm completely wrong in my method or understanding, please assist me.
I have a logic method I am testing. I've commented out the logic, but all it does is check a few values in the 'model' and returns if there's a problem. In the case we're looking at, there's no problem.
public ReplyDto SaveSettings(SnowballDto model)
{
// Some logic here that reads from the model.
var result = _data.SaveSettings(model);
return result;
}
My test, using NUnit and MOQ, looks like this:
_logic = new SnowballLogic(mockSnowballData.Object, mockLog.Object);
mockSnowballData
.Setup(x => x.SaveSettings(SnowballDto_Good))
.Returns(new ReplyDto {
IsSuccess = true,
Message = "Saved",
ReplyKeyID = 1
});
In each test, I call a private setup function that sets up the things I'll be using.
private void SetupData()
{
SnowballDto_Good = new SnowballDto {
FirstPaymentDate = DateTime.UtcNow,
ID = 1,
OrderedIDPriority = new List<int>(),
SnowballTypeID = 1,
TargetPayment = 1000
};
DebtDtoList_ThreeDebt.Clear();
DebtDtoList_ThreeDebt.Add(new DebtDto { ID = 1, Description = "Debt 1", ManualSnowballPriority = 1, MinimumMonthlyPaymentAmount = 140, OpeningBalance = 5000, RunningData = new DebtRunningDto { Balance = 5000 }, OpeningDate = DateTime.UtcNow, SnowballID = 1, StandardRate = 10 });
DebtDtoList_ThreeDebt.Add(new DebtDto { ID = 2, Description = "Debt 2", ManualSnowballPriority = 2, MinimumMonthlyPaymentAmount = 90, OpeningBalance = 1600, RunningData = new DebtRunningDto { Balance = 1600 }, OpeningDate = DateTime.UtcNow, SnowballID = 1, StandardRate = 15 });
DebtDtoList_ThreeDebt.Add(new DebtDto { ID = 3, Description = "Debt 3", ManualSnowballPriority = 3, MinimumMonthlyPaymentAmount = 300, OpeningBalance = 9000, RunningData = new DebtRunningDto { Balance = 9000 }, OpeningDate = DateTime.UtcNow, SnowballID = 1, StandardRate = 20 });
}
So, my understanding of MOQ is that I am saying "When the SnowballData class's "SaveSettings" methid is called, and a "SnowballDto_Good" object is passed in, always return a new ReplyDto with IsSuccess = true.
Therefore, when I make the call:
var result = _data.SaveSettings(model);
It should return ReplyDto with IsSuccess = true
However, when I put a breakpoint in when I call 'SaveSettings', it returns null all the time.
If I change my setup to:
.Setup(x => x.SaveSettings(It.IsAny<SnowballDto>()))
The test passes. Why is it returning null when I give it a real SnowballDto?
well, it seems you are passing an instance of SnowballDto named model in the "act" part of your test
var result = _data.SaveSettings(model);
In the setup of moq, however, you configure it to return a new ReplyDto only when the instance SnowballDto_Good is specified to SaveSettings. In all other cases, the method's mock is not configured, and - in case of a loose mocking strategy (the default) - it will return the default value for SaveSettings return type. In this case: null.
When you're using It.IsAny<SnowballDto> you are basically telling moq to configure SaveSettings to return a new instance not only then the instance SnowballDto_Good is passed to it, but any instance of that type.
What you need to do is to change your "act" part of your test as follows:
var result = _data.SaveSettings(SnowballDto_Good);
then it will work with your original mock setup, because the correct instance will be passed to SaveSettings.
This is precisely why I like to instantiate my mocks using MockBehavior.Strict.
Instead of returning null, it will throw an exception that will tell you that you didn't configure your mock correctly.
Hope this helps.

Creating C# Objects Dynamically

Currently having an issue creating a reusable object that I will need to use in a JSON construct string function.
Currently I have the following to create the bulk of the JSON string:
var data = new
{
record = new
{
value1 = Row.value1,
value2 = Row.value2,
form_values = new Dictionary<string, string>()
}
};
data.record.form_values["833b"] = Row.value3.ToString();
data.record.form_values["98wq"] = BuildMultiSelectList(Row.value3.ToString());
public object BuildMultiSelectList(string datavalue)
{
var choicelist = new {
choice_values: [datavalue],
other_values: [],
};
return choicelist;
}
The top half all works fine, though the function BuildMultiSelectList is giving errors such as "choice_values" does not exist in the current context and datavalue does not exist in the current context.
Any insight on why this has gone a bit rouge will be appreciated.
May be you are just mixing colon : with =?
var choicelist = new {
choice_values = new string[] {datavalue},
other_values = new[] {},
};

Add an anonymous class of object to an anonymous list

I've declare a anonymous list like this, and it contain list of contact also
var ContactGroup = new[] { new { ContactGroupKey = 0, ContactGroupTLK = 0, Desc = "", Contacts=new List<object>() } }.ToList();
I try to check the list, if the ContactGroupKey is exists then update only the Contacts(defined as a list) else insert a new contactgroup. but when i tried to add a new contactgroup inside my anonymous list its throw an error "The best overloaded method match for 'System.Collections.Generic.List.Add(AnonymousType#2)' has some invalid arguments
" I'm using anonymous list first time. I tried to avoid classes in this scenario. can any one suggest me where i made the mistake?
while()
{
var Contact= new {
ContactKey = Convert.ToInt64(DB["ContactKey", "0"]),
FirstName = DB["FirstName", ""].ToString(),
Surname = DB["Surname", ""].ToString(),
FullName = DB["Fullname", ""].ToString(),
Street = DB["bStreet", ""].ToString(),
City = DB["bCity", ""].ToString(),
};
foreach (var item in ContactGroup)
{
if (item.ContactGroupKey == Contact.ClaimContactGroupKey)
{
item.Contacts.Add(Contact);
added = true;
}
}
if(!added){
ContactGroup.Add(new {
ContactGroupKey = Convert.ToInt64(DB["ContactGroupKey", "0"]),
ContactGroupTLK = Convert.ToInt64(DB["TranslationKey", "0"]),
Desc = DB["Description", ""].ToString(),
Contacts=GenerateList(Contact)
});
}
}// End While
public static List<T> GenerateList<T>(T itemOftype)
{
List<T> newList = new List<T>();
return newList;
}
The problem is that the anonymous types you're using aren't the same. You need to get the properties to match in name, type and order. Look at this:
ContactGroup.Add(new {
ContactGroupKey = Convert.ToInt64(DB["ContactGroupKey", "0"]),
ContactGroupTLK = Convert.ToInt64(DB["TranslationKey", "0"]),
Desc = DB["Description", ""].ToString(),
Contacts=GenerateList(Contact)
});
That will have ContractGroupKey and ContactGruopTLK as long properties, and Contacts as a List<T> where T is your other anonymous type. You would need to change your initialization to be something like:
var sampleContact = new { ContactKey = 0L, /* etc */ };
var sampleContactList = new[] { sampleContact }.ToList();
var contactGroup = new[] { new { ContactGroupKey = 0L,
ContactGroupTLK = 0L,
Desc = "",
Contacts = sampleContactList } }.ToList();
That could work - but you'd be better off creating named classes for this. Ultimately it feels like these are likely to be significant entities in your system, so it's worth putting the effort into modelling them as named types to start with.
(Side note: it's worth being consistent in your naming; normally local variables are camelCased, so you should use contactGroup rather than ContactGroup, etc.)
Anonymous types are not intended to leave the current method. You cannot pass them to other methods. You should define a class containing the properties you need to handle.

Categories

Resources