How do I mock this value using Rhino Mocks - rhino-mocks

Here is the method I'm trying to test:
public override void CalculateReductionOnYield()
{
log.LogEnter();
if (illus.RpFundStreams.Count <= 0)
{
throw new InvalidDataException("No regular premium fund streams which are required in order to calculate reduction on yield");
}
// Add the individual ReductionOnYield classes to the collection.)
foreach (RegularPremiumFundStream fs in illus.RpFundStreams)
{
foreach (int i in ReductionOnYieldMonths)
{
ReductionOnYield roy = new ReductionOnYield(i);
roy.FundStream = fs;
ReductionsOnYield.Add(roy);
}
foreach (ReductionOnYield redOnYield in ReductionsOnYield)
{
if (redOnYield.Month == 0 || illus.RegularPremiumInPlanCurrency == 0M)
{
redOnYield.Reduction = 0M;
}
else
{
double[] regPremiums = new double[redOnYield.Month + 1];
for (int i = 1; i <= redOnYield.Month; i++)
{
regPremiums[i - 1] = Convert.ToDouble(-1*redOnYield.FundStream.FundStreamMonths[i].ValRegularPremium);
}
regPremiums[redOnYield.Month] = Convert.ToDouble(redOnYield.FundStream.GetFundStreamValue(redOnYield.Month));
redOnYield.Reduction = Convert.ToDecimal(Math.Pow((1 + Financial.IRR(ref regPremiums, 0.001D)), 12) - 1);
}
}
}
How do I mock all the required classes to test the value of redOnYield.Reduction to make sure that it working properly?
e.g. how do I mock redOnYield.FundStream.GetFundStreamValue(redOnYield.Month) and redOnYield.FundStream.FundStreamMonths[i].ValRegularPremium ?
Is this a valid test? Or am I going about this the wrong way?

without more info on your objects its hard to say, but you want something like:
var fundStream = MockRepository.GenerateStub<TFundStream>();
fundStream.Stub(f => f.GetFundStreamValue(60)).Return(220000M);
var redOnYeild = MockRepository.GenerateStub<TRedOnYeild>();
redOnYeild.Stub(r => r.FundStream).Return(fundStream);

redOnYield is an object returned from iterating ReductionsOnYield. I don't see where this is coming from. If we assume it's a virtual property, then you'll want to create a collection of mock ReductionOnYield objects and stub out ReductionsOnYield to return your mocked collection (or, to make it easier to test, have CalculateReductionOnYield accept an IEnumerable and operate on that collection).
Once you get the ReductionsOnYield issue resolved, Andrew's response of stubbing out the properties will get you where you want to be. Of course, this assumes that FundStream is virtual (so it can be mocked/stubbed) as well as RegularPremiumFundStream's GetFundStreamValue and FundStreamMonths.

Related

Update context in SQL Server from ASP.NET Core 2.2

_context.Update(v) ;
_context.SaveChanges();
When I use this code then SQL Server adds a new record instead of updating the
current context
[HttpPost]
public IActionResult PageVote(List<string> Sar)
{
string name_voter = ViewBag.getValue = TempData["Namevalue"];
int count = 0;
foreach (var item in Sar)
{
count = count + 1;
}
if (count == 6)
{
Vote v = new Vote()
{
VoteSarparast1 = Sar[0],
VoteSarparast2 = Sar[1],
VoteSarparast3 = Sar[2],
VoteSarparast4 = Sar[3],
VoteSarparast5 = Sar[4],
VoteSarparast6 = Sar[5],
};
var voter = _context.Votes.FirstOrDefault(u => u.Voter == name_voter && u.IsVoted == true);
if (voter == null)
{
v.IsVoted = true;
v.Voter = name_voter;
_context.Add(v);
_context.SaveChanges();
ViewBag.Greeting = "رای شما با موفقیت ثبت شد";
return RedirectToAction(nameof(end));
}
v.IsVoted = true;
v.Voter = name_voter;
_context.Update(v);
_context.SaveChanges();
return RedirectToAction(nameof(end));
}
else
{
return View(_context.Applicants.ToList());
}
}
You need to tell the DbContext about your entity. If you do var vote = new Vote() vote has no Id. The DbContext see this and thinks you want to Add a new entity, so it simply does that. The DbContext tracks all the entities that you load from it, but since this is just a new instance, it has no idea about it.
To actually perform an update, you have two options:
1 - Load the Vote from the database in some way; If you get an Id, use that to find it.
// Loads the current vote by its id (or whatever other field..)
var existingVote = context.Votes.Single(p => p.Id == id_from_param);
// Perform the changes you want..
existingVote.SomeField = "NewValue";
// Then call save normally.
context.SaveChanges();
2 - Or if you don't want to load it from Db, you have to manually tell the DbContext what to do:
// create a new "vote"...
var vote = new Vote
{
// Since it's an update, you must have the Id somehow.. so you must set it manually
Id = id_from_param,
// do the changes you want. Be careful, because this can cause data loss!
SomeField = "NewValue"
};
// This is you telling the DbContext: Hey, I control this entity.
// I know it exists in the DB and it's modified
context.Entry(vote).State = EntityState.Modified;
// Then call save normally.
context.SaveChanges();
Either of those two approaches should fix your issue, but I suggest you read a little bit more about how Entity Framework works. This is crucial for the success (and performance) of your apps. Especially option 2 above can cause many many issues. There's a reason why the DbContext keep track of entities, so you don't have to. It's very complicated and things can go south fast.
Some links for you:
ChangeTracker in Entity Framework Core
Working with Disconnected Entity Graph in Entity Framework Core

Insert Multiple records RIA services

I have a service class to hold the calls to the RIA service.
I have the following method to save multiple records, on the first step I should get the famous MaxId from the table and increment it in the foreach to add the objects.
public bool SaveRecs(ObservableCollection<Acc> accList)
{
int i = 0;
invokeOperation = Context.GetMaxAcc();
invokeOperation.Completed +=
(s, a) =>
{
foreach (Acc item in accList)
{
//if (CheckAcc(item.name, item.id)) continue;
item.id = invokeOperation.Value + i;
Context.Accs.Add(item);
i++;
}
};
return Commit();
}
The problem is that when the method is called first time, it do nothing and second time it works, the strange is that it may give an error of duplicate.
when I debug the code the id was ZERO
Is this the correct way of doing it?
thanks
My mistake, I should move the commit after the foreach.

Registering plugin on quick find in Dynamics CRM 2013

I have to register a plugin on Quick Find search on "Artilce" entity. When user enter any thing in quick find text box on Article entity at that time my plugin execute and return filter the data based on our business logic.
1.What event is fired when we find using quick find.
2.What message passes when this event is fired.
I have tried registering the plugin on RetrieveMultiple message but this is not triggered when we click on search in quick find.
Please help.
We have a Plugin registered on the RetrieveMultiple. We had a business requirement to search for the records, using WildCard by default.
Plugin Registration Details:
Message: RetrieveMultiple
Primary Entity:None
Secondary Entity:None
Pre-Operation
Code:
public const String QueryLiteral = "Query";
public const String LIKE = "%";
public void Execute(IServiceProvider serviceProvider)
{
String ParentEntity = String.Empty;
String OriginalSearch = String.Empty;
// Obtain the execution context from the service provider.
var ContextInstance = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
// Get a reference to the Organization service.
IOrganizationService ServiceInstance =
((IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory))).
CreateOrganizationService(ContextInstance.InitiatingUserId);
// Critical Point here - NOTICE that the InputParameters Contains the word Query
if (ContextInstance.Depth < 2 && ContextInstance.InputParameters.Contains(QueryLiteral) &&
ContextInstance.InputParameters[QueryLiteral] is QueryExpression)
{
QueryExpression QueryPointer = (ContextInstance.InputParameters[QueryLiteral] as QueryExpression);
//Verify the conversion worked as expected - if not, everything else is useless
if (null != QueryPointer)
{
// Check if the request is coming from any Search View
// We know this b/c Criteria isn't null and the Filters Count > 1
if (null != QueryPointer.Criteria && QueryPointer.Criteria.Filters.Count > 1)
{
ParentEntity = ContextInstance.PrimaryEntityName;
OriginalSearch = QueryPointer.Criteria.Filters[1].Conditions[0].Values[0].ToString();
OriginalSearch = String.Format(CultureInfo.CurrentCulture,
"{0}{1}", LIKE, OriginalSearch);
}
ConditionExpression NewCondition = null;
FilterExpression NewFilter = null;
if (null != QueryPointer.Criteria)
{
//Change the default 'BeginsWith'Operator to 'Contains/Like' operator in the basic search query
foreach (FilterExpression FilterSet in QueryPointer.Criteria.Filters)
{
foreach (ConditionExpression ConditionSet in FilterSet.Conditions)
{
if (ConditionSet.Operator == ConditionOperator.Like)
{
if (OriginalSearch != "")
ConditionSet.Values[0] = OriginalSearch;
else
{
OriginalSearch = QueryPointer.Criteria.Filters[0].Conditions[0].Values[0].ToString();
OriginalSearch = String.Format(CultureInfo.CurrentCulture,
"{0}{1}", LIKE, OriginalSearch);
ConditionSet.Values[0] = OriginalSearch;
}
}
}
}
}
}
ContextInstance.InputParameters[QueryLiteral] = QueryPointer;
}
}
Check details on this Post: http://www.williamgryan.mobi/?p=596
We have raised a ticket with Microsoft to address this situaation.
The solution they provided was to modify the Database to make the message
SearchByTitleKbArticleRequest available in the plugin registration tool.
I currently dont remember the table that we updated a flag against these messages.
After updating the table we were able to register the plugin against the message
SearchByTitleKbArticleRequest
Then the plugin triggered and we modified the entity collection returned from there.

dynamically change a part of the variable path

I know this question has been asked a bunch of times, but none of the answers (or at least what i took away from them) was a help to my particiular problem.
I want to dynamically change a part of the variable path, so i don't have to repeat the same code x-times with just two characters changing.
Here's what i got:
In the beginning of my script, i'm setting the reference to PlayerData scripts, attached to the GameManager object like this:
var P1 : P1_Data;
var P2 : P2_Data;
function Start(){
P1 = GameObject.Find("GameManager").GetComponent.<P1_Data>();
P2 = GameObject.Find("GameManager").GetComponent.<P2_Data>();
}
Later, i want to access these scripts using the currentPlayer variable to dynamically adjust the path:
var currentPlayer : String = "P1"; //this actually happens along with some other stuff in the SwitchPlayers function, i just put it here for better understanding
if (currentPlayer.PlayerEnergy >= value){
// do stuff
}
As i was afraid, i got an error saying, that PlayerEnergy was not a part of UnityEngine.String.
So how do I get unity to read "currentPlayer" as part of the variable path?
Maybe some parse function I haven't found?
Or am I going down an entirely wrong road here?
Cheers
PS: I also tried putting the P1 and P2 variables into an array and access them like this:
if (PlayerData[CurrentPlayerInt].PlayerEnergy >= value){
// do stuff
}
to no success.
First of all,
var currentPlayer : String = "P1"
here P1 is just string, not the previous P1/P2 which are referenced to two scripts. So, if you want, you can change
currentPlayer.PlayerEnergy >= value
to
P1.PlayerEnergy >= value
or,
P2.PlayerEnergy >= value
But if you just want one function for them, like
currentPlayer.PlayerEnergy >= value
Then you have to first set currentPlayer to P1/P2 which I assume you are trying to do. You must have some codes that can verify which player is selected. Then, maybe this can help -
var playerSelected: int = 0;
var currentPlayerEnergy: int = 0;
.....
//Use your codes to verify which player is selected and then,
if (playerSelected == 1) {
currentPlayerEnergy = P1.PlayerEnergy;
} else if (playerSelected == 2) {
currentPlayerEnergy = P2.PlayerEnergy;
}
//Now use your favorite function
if (currentPlayerEnergy >= value) {
//Do stuff
}
As there was no reply providing the answer I needed, I'll share the solution that did the trick for me, provided by a fellow student.
Instead of having the PlayerData scripts pre-written, I generate them using a public class function in a Playermanager script. This generates the Playerdata as attached scripts, saved into an array.
I can then access them through Playermanager.Playerlist[Playernumber].targetvariable.
Which is what I wanted to do, only with the Playerdata being attached to a script instead of a gameobject. And it works great!
Here's the full code of my Playermanager Script:
//initialise max players
public var maxplayers : int = 2;
// Initialise Playerlist
static var Players = new List.<PlayerData>();
function Start () {
for (var i : int = 0; i < maxplayers; i++){
var Player = new PlayerData();
Players.Add(Player);
Players[i].PlayerName = "Player " + i;
}
DontDestroyOnLoad (transform.gameObject);
}
public class PlayerData {
public var PlayerName : String;
public var PlayerEnergy : int = 15;
public var Fleet : List.<GameObject> = new List.<GameObject>();
}
As you see, you can put any type of variable in this class.
I hope this helps some of you who have the same problem.
cheers,
Tux

TFS SDK : Get Child Branches

What I want to do is to get the available branches that I can merge to. Pretty much the same as the dropdown when you say merge in TFS2008 and you select the destination branch.
However, it's been very hard to find how.
Below code is a merge between some of the resources I've found in the web, but none seem to work. My guess is that if VS2008 can do it, I can do it thru the SDK, right?.
The below code always give me the same result all the time.
My repository is something like this:
Development
Version1
Code
Version2
Code
Version3
Code
Main
Code
And normally I branch Main > Version X. So the merging can be done Main > Version X and Version X to Main.
The below code always gives me the children of the Main, even if I'm querying (tfsParentBranchPath) with Version3 folder.
Is this because perhaps I used TFS2010 web service but pointing to TFS2008 (that's why I marked some methods that do not work in the code)?
Well please let me know, if someone knows the answer.
Thanks!
public string[] GetChildBranchesToMerge(string tfsParentBranchPath)
{
var versionControl = teamFoundationServer.GetService<VersionControlServer>();
//not supported by tfs2008
//ItemIdentifier[] identifiers = versionControl.QueryMergeRelationships(tfsParentBranchPath);
//var allBranches = versionControl.QueryBranchObjects(new ItemIdentifier(tfsParentBranchPath), RecursionType.OneLevel);
List<string> childs = new List<string>();
ItemSpec[] specs = new ItemSpec[] { new ItemSpec(tfsParentBranchPath, RecursionType.OneLevel) };
BranchHistoryTreeItem[][] branchHistoryTree = versionControl.GetBranchHistory(specs, VersionSpec.Latest);
if (branchHistoryTree.Length > 0 && branchHistoryTree[0].Length > 0)
{
var treeItem = branchHistoryTree[0][0];
if (treeItem.Children.Count > 0)
{
foreach (BranchHistoryTreeItem tia in treeItem.Children)
{
childs.Add(tia.Relative.BranchToItem.ServerItem);
}
}
}
return childs.OrderBy((s) =>
{
return s;
}).ToArray();
}
Finally, this is the last version that works!.
First, I stopped using VS2010 assemblies and it's much faster now.
Second, the big difference is this line:
var treeItem = branchHistoryTree[0][0].GetRequestedItem();
I really dont know why the difference, but it seems without that method, the item returned is a generic one.
public string[] GetChildBranchesToMerge(string tfsParentBranchPath)
{
DoLog("Getting child branches for {0} ...", tfsParentBranchPath);
VersionControlServer vcs = (VersionControlServer)teamFoundationServer.GetService(typeof(VersionControlServer));
List<string> childs = new List<string>();
ItemSpec[] specs = new ItemSpec[] { new ItemSpec(tfsParentBranchPath, RecursionType.OneLevel) };
BranchHistoryTreeItem[][] branchHistoryTree = vcs.GetBranchHistory(specs, VersionSpec.Latest);
if (branchHistoryTree.Length > 0 && branchHistoryTree[0].Length > 0)
{
var treeItem = branchHistoryTree[0][0].GetRequestedItem();
AddChildBranch(childs, treeItem, tfsParentBranchPath);
if (treeItem.Children != null && treeItem.Children.Count > 0)
{
foreach (BranchHistoryTreeItem tia in treeItem.Children)
{
AddChildBranch(childs, tia, tfsParentBranchPath);
}
}
}
DoLog("{0} child branches found", childs.Count);
return childs.OrderBy((s) =>
{
return s;
}).ToArray();
}
private void AddChildBranch(List<string> list, BranchHistoryTreeItem itemToCheck, string tfsParentBranchPath)
{
if (itemToCheck.Relative.BranchFromItem != null && itemToCheck.Relative.BranchFromItem.DeletionId == 0 && itemToCheck.Relative.BranchFromItem.ServerItem != tfsParentBranchPath)
list.Add(itemToCheck.Relative.BranchFromItem.ServerItem);
if (itemToCheck.Relative.BranchToItem != null && itemToCheck.Relative.BranchToItem.DeletionId == 0 && itemToCheck.Relative.BranchToItem.ServerItem != tfsParentBranchPath)
list.Add(itemToCheck.Relative.BranchToItem.ServerItem);
}