MOQ - Mock a Dictionary<string, double> object - asp.net-mvc-3

I have the following setup for Moq:
... other code to setup bigMoq object ...
var innerMoq = new Mock<IDictionary<string, double>>();
innerMoq.SetupGet(d => d["COMPLEX"]).Returns(6d);
innerMoq.SetupGet(d => d["MEDIUM"]).Returns(8d);
innerMoq.SetupGet(d => d["SIMPLE"]).Returns(10d);
bigMoq.SetupGet(d => d.ComplexityWeights).Returns(x.Object);
When running a test method, I pass in bigMoq as the arguement.
The following works:
bigMoqVar.ComplexityWeights["COMPLEX"] // correctly returns 6
However, this does not:
bigMoqVar.ComplexityWeights.ContainsKey("COMPLEX") // returns false instead of true
What is the recommended way to support the ContainsKey on the innerMoq?

That's because you didn't setup an expectation for ContainsKey. You will need to setup that manually, Moq has no knowledge of the semantics of the interface.
innerMoq.Setup(d => d.ContainsKey("COMPLEX")).Returns(true);
However, if this is just an IDictionary you need, why go through the mocking framework ? Just create a Dictionary<string,double> with the objects you need.

Related

How to create an Aurelia-Validation Validation object for Jasmine tests

I'm currently using the Aurelia-Validation plugin to do client side validation. Since the validation object must be injected into the calling class's constructor, all my jasmine tests for the class in question now fail(since there's no validation object being passed in)
I've been trying to create a mock Validation object for a while now, or even a real one but i can't seem to get it right. The closest I've gotten is:
beforeEach(() => {
cache = new Cache();
session = new Session();
var valCon = new ValidationConfig();
var obsLoc = new ObserverLocator();
sut = new InsuredInformation(session, cache, new Validation(obsLoc,valCon));
});
But I keep getting errors when I run Karma saying:
TypeError: Expecting a function in instanceof check, but got [object Object]
I'm assuming this has something to do with the validation object and how i have instantiated it. Has anyone successfully created Jasmine tests for Aurelia View-Models that make use of the aurelia-validation plugin?
Try using the Container to instantiate your object. You may need to initialize the platform abstraction layer.
import {Container} from 'aurelia-framework'; // or 'aurelia-dependency-injection'
import {initialize as initializePAL} from 'aurelia-pal-browser'; // you may need to `jspm install aurelia-pal-browser`
initializePAL();
beforeEach(() => {
let container = new Container();
sut = container.get(InsuredInformation);
foo = container.get(SomeOtherClassThatYouWantToTest);
});

C# ElasticSeach Mock Suggestions

I am trying to mock a suggest response, however suggestionOption.Setup(x => x.Text).Returns("Hello") is throwing an exception:
An exception of type System.NotSupportedException occurred in
Moq.dll but was not handled in user code Additional information:
Invalid setup on a non-virtual (overridable in VB) member: x => x.Text
var searchSuggestResponseMock = new Mock<ISuggestResponse>();
var suggestionOption = new Mock<SuggestOption>();
suggestionOption.Setup(x => x.Text).Returns("Hello");
suggestionOption.Setup(x => x.Payload).Returns("{path:\"drugs/hello\"}");
var suggestion = new Mock<Suggest>();
suggestion.Setup(x => x.Options).Returns(new List<SuggestOption> { suggestionOption.Object });
searchSuggestResponseMock.Setup(x => x.Suggestions).Returns(new Dictionary<string, Suggest[]>()
{
{"suggest", new Suggest[] {suggestion.Object}},
});
var mock = new Mock<IConnector>();
mock.Setup(x => x.getClient()
.Suggest<Term>(Moq.It.IsAny<Func<SuggestDescriptor<Term>,
SuggestDescriptor<Term>>>())).Returns(searchSuggestResponseMock.Object);
_connector = mock.Object;
You can't mock non-virtual methods. As the error states:
Invalid setup on non-virtual member
Moq does its magic by acting as a proxy between your code and the real class. It does this by taking advantage of virtual methods. Without having a virtual method, Moq can't intercept the call.
Neither SuggestionOption, or Suggest are easily mockable, as they have non-virtual, internal set based properties, and do not implement any specific interface.
It looks like you are maybe mocking at too low a level. If you don't want to call Elastic to get your list of suggestions then have a method which just returns an array of strings (or your own custom Suggestion class) and mock that instead.
Or just call Elastic for real, as long as you are passing in sensible values which don't return thousands of suggestions.
(Or you could in theory create instances of Suggest, and set the internal properties via reflection, but this is not ideal obviously).

Can you record accessed methods in Visual Studio?

I'm retroactively documenting and writing unit tests for some C# code. I would like to determine what code is actually being used and when.
In Visual Studio 2012, is there a way to record all the methods accessed and in what order while walking through specific scenarios?
You could run your application with a profiler attached, which will give you all accessed methods, call chains, counts, etc.
The Visual Studio Profiler will give you the time spent in each method, and let you inspect the call heirarchy. I don't know if it will give you the exact order they were called in though.
EDIT: Apparently attaching the profiler to a running unit test is harder in VS2012.
Are you wanting to execute a test method that make sure that a particular method on a class was invoked ? If so i dont know of a way to do it in VS alone, but you can use a mock framework to create dependency mocks and check values on them. Here is a snippet of a unit test:
[TestMethod]
public void HttpPostPrivacyPolicyFacadeSvcErrorTest()
{
var controller = ControllerHelper.GetRouteController();
controller.Session[SessionVariable.User] = new UserInfo() { UserName = Config.Data.Username };
var idmSvcMock = new Mock<IUserServiceDAO>();
var facadeSvcMock = new Mock<IFacadeSvcDAO>();
//setup the facade mock to throw exception to simulate FacadeServiceException
facadeSvcMock.Setup(x => x.SetPrivacyAcceptanceStatus(It.IsAny<UserInfo>())).Throws<Exception>();
var userCollectorMock = new Mock<IUserInfoCollector>();
userCollectorMock.Setup(x => x.GetUserInfo()).Returns(new UserInfo() { UserName = Config.Data.Username });
controller.FacadeSvc = facadeSvcMock.Object;
controller.UserServiceDAO = idmSvcMock.Object;
controller.UserCollector = userCollectorMock.Object;
controller.DefaultErrorId = "Route_errors_Unabletoprocess";
//action
var res = controller.Privacy(new FormCollection());
//assert
//make sure we go to the right controller, action, with the correct params.
res.AssertActionRedirect().ToController("Errors").ToAction("Index").WithParameter("id", "Route_errors_Unabletoprocess");
//did we call setprivacy once on the mock?
facadeSvcMock.Verify(x => x.SetPrivacyAcceptanceStatus(It.IsAny<UserInfo>()), Times.Exactly(1));
In the test above i check that SetPrivacyAcceptance was invoked once and only once on my facadeSvcMock instance. More on moq here: Moq
this block of code is actually checking how many times SetPrivacyAcceptanceStatus was invoked:
//did we call setprivacy once on the mock?
facadeSvcMock.Verify(x => x.SetPrivacyAcceptanceStatus(It.IsAny()), Times.Exactly(1));
the It.IsAny() is the one parameter to that method, so the line above says basically "For any input parameter of type UserInfo verify that we invoked SetPrivacyAcceptanceStatus exactly once."

Custom Matching with Moq

I am attempting to be a good TDD citizen as I design an application. I'm using Moq, and I've run into a little repository issue.
My repository has a Find method:
public IEnumerable<T> Find(Expression<Func<T, bool>> where)
{
return _objectSet.Where(where);
}
Then I attempt to set up a mock of the repository:
mock.Setup(m => m.Find(c => c.ConferenceID == conferenceID))
.Returns(ConferenceTestObjectContainer.CreateConferences().Where(c => c.ConferenceID == conferenceID).ToList());
The test will work if I test against the mock directly in the test, but if I inject the mock into my production code (an ASP.NET page in this case,) and test the page method, it doesn't work.
Justin Etheredge addresses the problem in his post here. The issue is that the comparer between the call and the setup can't handle Expressions so well.
The problem that I'm having is with his comparer function:
public static Expression<Func<T,bool>> AreEqual<T>(Expression<Func<T,bool>> expr)
{
return Match<Expression<Func<T, bool>>>
.Create(t => t.ToString() == expr.ToString());
}
This raises a compiler error:
The type arguments for method 'Moq.Match.Create(System.Predicate)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
I understand that the compiler can't infer the type of "T", but I'm not clear on how to fix that. The good Mr. Etheredge made this work, but I don't understand what I'm doing wrong.
TIA.
OK, so this question is going Tumblweed...
For the record, I worked around the problem by deriving a new Entity-specific Repository and added a FindById() method, which works great.
Why don't you use somenthing like this:
public static Expression<Func<T,bool>> AreEqual<T>(Expression<Func<T,bool>> expr)
{
return Match.Create<Expression<Func<T, bool>>>(t => t.ToString() == expr.ToString());
}
In this way I'm handling generic as well.

Asserting that a method is called exactly one time

I want to assert that a method is called exactly one time. I'm using RhinoMocks 3.5.
Here's what I thought would work:
[Test]
public void just_once()
{
var key = "id_of_something";
var source = MockRepository.GenerateStub<ISomeDataSource>();
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.Repeat.Once();
var client = new Client(soure);
// the first call I expect the client to use the source
client.GetMeMyThing(key);
// the second call the result should be cached
// and source is not used
client.GetMeMyThing(key);
}
I want this test to fail if the second invocation of GetMeMyThing() calls source.GetSomethingThatTakesALotOfResources().
Here's how I'd verify a method is called once.
[Test]
public void just_once()
{
// Arrange (Important to GenerateMock not GenerateStub)
var a = MockRepository.GenerateMock<ISomeDataSource>();
a.Expect(x => x.GetSomethingThatTakesALotOfResources()).Return(new Something()).Repeat.Once();
// Act
// First invocation should call GetSomethingThatTakesALotOfResources
a.GetMeMyThing();
// Second invocation should return cached result
a.GetMeMyThing();
// Assert
a.VerifyAllExpectations();
}
I have been using the AssertWasCalled extension to get around this problem. This is the best I could find/come up with but it would be better if I didn't have to specify the call twice.
[Test]
public void just_once()
{
var key = "id_of_something";
var source = MockRepository.GenerateStub<ISomeDataSource>();
// set a positive expectation
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.Repeat.Once();
var client = new Client(soure);
client.GetMeMyThing(key);
client.GetMeMyThing(key);
source.AssertWasCalled(x => x.GetSomethingThatTakesALotOfResources(key),
x => x.Repeat.Once());
source.VerifyAllExpectations();
}
You may be interested in this bit from the Rhino Mocks 3.5 Documentation (quoted below). Looks like you need to mock the class, not stub it, for it to work the way you expect.
The difference between stubs and mocks
...
A mock is an object that we can set
expectations on, and which will verify
that the expected actions have indeed
occurred. A stub is an object that you
use in order to pass to the code under
test. You can setup expectations on
it, so it would act in certain ways,
but those expectations will never be
verified. A stub's properties will
automatically behave like normal
properties, and you can't set
expectations on them.
If you want to verify the behavior of
the code under test, you will use a
mock with the appropriate expectation,
and verify that. If you want just to
pass a value that may need to act in a
certain way, but isn't the focus of
this test, you will use a stub.
IMPORTANT: A stub will never cause a
test to fail.
Here is what I just did (as recommended by Ray Houston). I would still appreciate a more elegant solution...
[Test]
public void just_once()
{
var key = "id_of_something";
var source = MockRepository.GenerateStub<ISomeDataSource>();
// set a positive expectation
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.Repeat.Once();
var client = new Client(soure);
client.GetMeMyThing(key);
// set a negative expectation
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.Repeat.Never();
client.GetMeMyThing(key);
}
You can pass a delegate to WhenCalled to count calls:
...
uint callCount = 0;
source.Expect(x => x.GetSomethingThatTakesALotOfResources(key))
.Return(new Something())
.WhenCalled((y) => { callCount++; });
...
Assert.AreEqual(1, callCount);
Also, you should use a mock not a stub, and verify expectations on the mock too.
You can create strict mock, if you want to ensure that a method is called only once.
var mock = MockRepository.GenerateStrictMock<IMustOnlyBeCalledOnce>();
mock.Expect(a => a.Process()).Repeat.Once();
var helloWorld= new HelloWorld(mock);
helloworld.Process()
mock.VerifyAllExpectations();
Having a feature called "Exactly" would be handy to write tests on code that might otherwise get into an infinite loop. I would love to write a test such that the second call to a method would raise an exception.
Some libraries for python allow you to sequence expectations, so the first returns false and the second raises an exception.
Rhino won't do that. A partial mock with .Once will intercept the first call, and the rest will be passed on to the original method. So that sucks, but it's true.
You'll have to create a hand-mock. Derive a "testable" class, and give it the ability to raise after the first call.

Resources