The SetupGet for Form work, but the Count not work. How to resolve to Count return the value expected?
var httpContextMock = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
httpContextMock.SetupGet(x => x.Request).Returns(request.Object);
httpContextMock.SetupGet(x => x.Request.Form).Returns(form);
httpContextMock.SetupGet(x => x.Request.Files.Count).Returns(2);
It is not working because you are setting up the wrong mock. Apply the setup on the request mock.
var httpContextMock = new Mock<HttpContextBase>();
var requestMock = new Mock<HttpRequestBase>();
requestMock.Setup(_ => _.Form).Returns(form);
requestMock.Setup(_ => _.Files.Count).Returns(2);
httpContextMock.Setup(_ => _.Request).Returns(requestMock.Object);
Just to prove the above works, I tested it like this
var context = httpContextMock.Object;
Assert.AreEqual(2, context.Request.Files.Count);
and it worked.
I did a quick test and it works if you access the request through the mock context.
[Test()]
public void Test()
{
var httpContextMock = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
httpContextMock.SetupGet(x => x.Request).Returns(request.Object);
httpContextMock.SetupGet(x => x.Request.Files.Count).Returns(2);
var count = httpContextMock.Object.Request.Files.Count;
Assert.AreEqual(2, count);
}
As Nkosi suggested, however, you probably wanted to setup Files.Count on the requestMock itself.
Related
Is there any way to use OmitAutoProperties except entity.Id (Key) and only User.Id (ForeignKey)?
var user = new Fixture().Build<User>().Create();
var entity = new Fixture().Build<Game>().With(x => x.User, user).Create();
You can use With:
var fixture = new Fixture();
var user = fixture
.Build<User>()
.OmitAutoProperties()
.With(p => p.Id)
.Create();
var entity = fixture
.Build<Game>()
.OmitAutoProperties()
.With(p => p.Id)
.With(p => p.User, user)
.Create();
I have the following test code.
var test = "Test";
var command = new MyCommand { V = test };
var mock = new Mock<IRepository>(); // IRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(p)).Verifiable();
var sut = new C(mock.Object);
var result = await sut.M(command);
mock.Verify();
The test should pass. However, it failed with the error of,
Message:
Moq.MockException : Mock:
This mock failed verification due to the following:
IRepository x => x.Save(P):
This setup was not matched.
Stack Trace:
Mock.Verify()
sut.M() will convert a string X to type P with value of P(X).
It seems to me that you want to verify that the Save method from your mock is called with a specific value, and not just a type.
I have tried something like the following and believe it should work. I have modified your example.
var test = "Test";
var command = new MyCommand { V = test };
var mock = new Mock<IRepository>(); // IRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(It.IsAny<P>());
var sut = new C(mock.Object);
var result = await sut.M(command);
mock.Verify(x => x.Save(It.Is<P>(v => v.Value.Equals(p.Value))), Times.AtLeastOnce);
This tests that the values of the specific property are equal.
I Tested this with the following test:
var test = "Test";
var mock = new Mock<ITestRepository>(); // ITestRepository has the method of Save()
var p = new P(test);
mock.Setup(x => x.Save(It.IsAny<P>()));
mock.Object.Save(new P(test));
mock.Verify(x => x.Save(It.Is<P>(v => v.Value.Equals(p.Value))), Times.AtLeastOnce);
I have a controller which requires both Session state object and also Url Helper to be mocked from unit test and in this regard i have created the following below code
[TestMethod]
public void PaymentControllerTest_CallPaymentProvider()
{
var controller = new PaymentController();
// var model = new Dictionary<string, string>();
var mockDatabaseWrapper = new MockDatabaseWrapper();
DatabaseWrapper.SetDatabaseWrapper(mockDatabaseWrapper);
var request = new Mock<HttpRequestBase>();
request.SetupGet(x => x.Headers).Returns(
new System.Net.WebHeaderCollection {
{"X-Requested-With", "XMLHttpRequest"} });
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost"));
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
controller.ControllerContext = new ControllerContext(context.Object, new System.Web.Routing.RouteData(), controller);
controller.Url = new UrlHelper(new System.Web.Routing.RequestContext(controller.HttpContext, new RouteData()), new RouteCollection());
RouteCollection routes = new System.Web.Routing.RouteCollection();
var mockControllerContext = new Mock<ControllerContext>();
var mockSession = new Mock<HttpSessionStateBase>();
mockSession.SetupGet(Session => Session["CurrentCulture"]).Returns(1); //somevalue
mockControllerContext.Setup(p => p.HttpContext.Session).Returns(mockSession.Object);
var result = controller.CallPaymentProvider(123) as ViewResult;
}
Now the problem is that when i create the controller context i am able to pass only one. can any of the experts help how to pass both session and url in controller context.
Thanks
When I do these two lines after each other my code fails with Previous method 'HttpContextBase.get_Request();' requires a return value or an exception to throw. on the second line.
context.Expect(c => c.Request.UrlReferrer).Return(uri).Repeat.Any();
context.Expect(c => c.Request.HttpMethod).Return("POST").Repeat.Any();
However when I do just one of the rows the code runs fine.
Doing the following does not fix the problem.
context.Expect(c => c.Request).Return(request);
Anyone understands this strange behaviour?
Thanks,
Drutten
Edit: Entire code is:
public static class Extensions
{
public static HttpContextBase FakeHttpContext()
{
var context = MockRepository.GenerateMock<HttpContextBase>();
var request = MockRepository.GenerateMock<HttpRequestBase>();
var response = MockRepository.GenerateMock<HttpResponseBase>();
var session = MockRepository.GenerateMock<HttpSessionStateBase>();
var server = MockRepository.GenerateMock<HttpServerUtilityBase>();
var writer = new StringWriter();
var form = new NameValueCollection();
request.Expect(r => r.Form).Return(form);
var uri = new Uri("http://localhost/IntegrationTests");
request.Expect(r => r.UrlReferrer).Return(uri).Repeat.Any();
var queryString = new NameValueCollection();
request.Expect(r => r.QueryString).Return(queryString);
context.Expect(c => c.Request).Return(request).Repeat.Any();
context.Expect(c => c.Request.UrlReferrer).Return(uri).Repeat.Any();
context.Expect(c => c.Request.HttpMethod).Return("POST").Repeat.Any();
context.Expect(c => c.Response).Return(response);
context.Expect(c => c.Session).Return(session);
context.Expect(c => c.Server).Return(server);
context.Expect(c => c.Items).Return(new Dictionary<object, object>());
response.Expect(c => c.Output).Return(writer);
return context;
}
public static void MockControllerContext(this Controller controller)
{
var httpContext = FakeHttpContext();
var routeData = new RouteData();
routeData.Values.Add("controller", "Home");
routeData.Values.Add("action", "Index");
controller.ControllerContext = new ControllerContext(new RequestContext(httpContext, routeData), controller);
}
}
I fixed the problem. The problem was probably related to the mix of
context.Expect(c => c.Request.UrlReferrer).Return(uri).Repeat.Any();
and
context.Expect(c => c.Request).Return(request).Repeat.Any();
Working code is:
var uri = new Uri("http://localhost/IntegrationTests");
request.Expect(r => r.UrlReferrer).Return(uri).Repeat.Any();
var queryString = new NameValueCollection();
request.Expect(r => r.QueryString).Return(queryString);
request.Expect(c => c.HttpMethod).Return("POST").Repeat.Any();
context.Expect(c => c.Request).Return(request).Repeat.Any();
I find it strange though that doing
context.Expect(c => c.Request.HttpMethod).Return("POST").Repeat.Any();
once worked, even when not setting return on Request.
Hi I am trying to set an mock of a class's method with two possible input. When i check output only the last set up return expected output. The first one did not. Any help is much appreciated.
[Test]
public void ClimbOnceTwoNeighbour_Sample()
{
stateConverter = new Mock<StateConverter>();
solution = new Mock<Solution>();
state = new Mock<State>();
var neightbourSolution1 = new Mock<Solution>();
var neighbourState1 = new Mock<State>();
var neightbourSolution2 = new Mock<Solution>();
var neighbourState2 = new Mock<State>();
stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);
var state1 = stateConverter.Object.FromSolution(neightbourSolution1.Object, state.Object);//return null ????
var state2 = stateConverter.Object.FromSolution(neightbourSolution2.Object, state.Object);//return neighbourState2.Object)
Assert.AreEqual(neighbourState2.Object, state2);//pass test here
Assert.AreEqual(neighbourState1.Object, state1);//fail here due to null is returned from previous statement
}
I have copied your code snippet and created empty classes to make it compile. It works as expected. Try it please and let me know what was the result.
Here is the code:
using Moq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var stateConverter = new Mock<StateConverter>();
var solution = new Mock<Solution>();
var state = new Mock<State>();
var neightbourSolution1 = new Mock<Solution>();
var neighbourState1 = new Mock<State>();
var neightbourSolution2 = new Mock<Solution>();
var neighbourState2 = new Mock<State>();
stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);
var state1 = stateConverter.Object.FromSolution(neightbourSolution1.Object, state.Object);
var state2 = stateConverter.Object.FromSolution(neightbourSolution2.Object, state.Object);
}
}
public class State{}
public class Solution{}
public abstract class StateConverter
{
public abstract State FromSolution(Solution p0, State isAny);
}
}
One of the habits I've got into with Moq is to use the full It.Is(o => o == object) syntax to avoid any issues when the setup could be ambiguous or implicit. It could be that Moq is simply taking the object in the setup and overriding any others it already had there.
stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);
Would then look like
stateConverter.Setup(x => x.FromSolution(It.Is<Solution>(solution => solution == neightbourSolution1.Object), It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(It.Is<Solution>(solution => solution == neightbourSolution2.Object), It.IsAny<State>())).Returns(neighbourState2.Object);
I'm not too sure if this would solve your issue as the implicitness is pretty damn clear. :/
Have you tried something like this?
[Test]
public void ClimbOnceTwoNeighbour_Sample()
{
stateConverter = new Mock<StateConverter>();
solution = new Mock<Solution>();
state = new Mock<State>();
var neightbourSolution1 = new Mock<Solution>();
var neighbourState1 = new Mock<State>();
var neightbourSolution2 = new Mock<Solution>();
var neighbourState2 = new Mock<State>();
stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
var state1 = stateConverter.Object.FromSolution(neightbourSolution1.Object, state.Object);//return null ????
stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);
var state2 = stateConverter.Object.FromSolution(neightbourSolution2.Object, state.Object);//return neighbourState2.Object)
Assert.AreEqual(neighbourState2.Object, state2);//pass test here
Assert.AreEqual(neighbourState1.Object, state1);//fail here due to null is returned from previous statement
}
I think that this way, when you assing to your state1 the result of the first return, you can use Setup again and add the result to state2 ;)