Rhino Mocks - Arg<T> to ommit some parameters - c#

I am using Rhino Mocks to stub out the functionality of a SOAP endpoint and for the most part it works. But, the interface is quite quirky and I am struggling to get the following to work (i have renamed the classes for simplicity)
public interface IWebService
{
void CopyFile(Request request);
}
public interface IService
{
void CopyFile(string filename, byte[] data);
}
public class Request
{
public string Filename { get; set; }
public byte[] Data { get; set; }
}
public class Service : IService
{
IWebService _service;
public Service(IWebService service)
{
_service = service;
}
public void CopyFile(string filename, byte[] data)
{
_service.CopyFile(new Request() {Filename = filename,Data = data });
}
}
Now, in my test I have something like this
[TestCase]
public void TestFileCopyFailsIfFilenameIsMissing()
{
IWebService serviceMock = MockRepository.GenerateMock<IWebService>();
serviceMock.Expect(x => x.CopyFile(Arg<Request>.Is.Equal(new Request() { Filename = Arg<string>.Is.Null, Data = Arg<byte[]>.Is.Anything }))).Throw(new Exception());
Service service = new Service(serviceMock);
service.CopyFile(null, new byte[] { });
}
Which throws the exception:
An exception of type 'System.InvalidOperationException' occurred in Rhino.Mocks.dll but was not handled in user code
Additional information: Use Arg ONLY within a mock method call while recording. 1 arguments expected, 3 have been defined.
I have tried the all possibilities in the world on this one, but cant get it right. If i dont use Arg and use
Expect(null, new byte[]{});
it will always pass no matter what

I suggest to use WhenCalled and in this method check Request object.
bool isCorrectParam = false;
IWebService serviceMock = MockRepository.GenerateMock<IWebService>();
serviceMock.Expect(x => x.CopyFile(null))
.IgnoreArguments()
.WhenCalled(x =>
{
Request req = x.Arguments[0] as Request;
if (req.Data.Count() == 0 && req.Filename == null)
{
isCorrectParam = true;
}
});
Service service = new Service(serviceMock);
service.CopyFile(null, new byte[] { });
Assert.IsTrue(isCorrectParam);

you can also use Matches...
serviceMock.Expect(x => x.CopyFile(Arg<Request>.Matches(r => r.FileName==null))).Throw(new Exception());

Related

Mock custom implementation of CodeAccessSecurityAttribute

I have a custom implementation of CodeAccessSecurityAttribute that is connecting external sources to do a validation.
[Serializable]
[AttributeUsage(AttributeTargets.Method)]
public class IsAuthorizedAttribute : CodeAccessSecurityAttribute
{
private static readonly PrincipalPermission Allowed = new PrincipalPermission(PermissionState.None);
private static readonly PrincipalPermission NotAllowed = new PrincipalPermission(PermissionState.Unrestricted);
public string EntityObject { get; set; }
public string Field { get; set; }
public char Expected { get; set; }
public IsAuthorizedAttribute(SecurityAction action)
: base(action)
{
//setup
}
public override IPermission CreatePermission()
{
return IsAuthorised(EntityObject, Field, Expected, ServicesConfiguration) ? Allowed : NotAllowed;
}
private static bool IsAuthorised(string entityObject, string field, char expected, ServicesConfiguration servicesConfiguration)
{
bool? response = null;
//check external stuff
return response ?? false;
}
}
I have decorated my methods with this attribute:
[IsAuthorized(SecurityAction.Demand, EntityObject = Fields.UserManagement, Field = Fields.AllowDisplay, Expected = '1')]
public List<Group> GetUserGroups()
{
var response = new List<Group>();
//Get the groups from the database
var groups = groupManager.FindAll();
//Map them to the output group type
response = groups.Select(x => new Group()
{
ID = x.ID,
Name = x.Name,
Alias = x.Alias,
Description = x.Description
}).ToList();
return response;
}
I now want to unit test this method, but the attribute is fired. I have tried some things to mock the attribute, but without success.
I'm using Moq and Smocks.
This is my unit test without a mocked instance of the attribute:
[TestMethod]
public void GetUserGroups_UserGroupsFound_UserGroupsReturned()
{
Smock.Run(context =>
{
//Arrange
Setup();
m_Container
.RegisterMock<IGroupManager>()
.Setup(x => x.FindAllFromCache())
.Returns(new List<Concept.Security.MasterData.Domain.Group>()
{
new Concept.Security.MasterData.Domain.Group()
{
Name = "MyUserGroup",
Alias = "My User Group",
Description = "My user group description",
System = false,
Authorizations = "000001111100000000"
},
new Concept.Security.MasterData.Domain.Group()
{
Name = "MySecondUserGroup",
Alias = "My Second User Group",
Description = "My second user group description",
System = false,
Authorizations = "000000000000000000"
}
});
var identityService = new UserManagementService(m_Container, m_UserAuthorizationManager.Object, m_IdentityService.Object);
//** begin add mocked attribute **//
//** end add mocked attribute **//
//Act
var response = identityService.GetUserGroups();
//Assert
Assert.AreEqual(2, response.Count);
Assert.AreEqual(1, response.Where(x => x.Alias == "MyUserGroup").Count());
Assert.AreEqual(1, response.Where(x => x.Alias == "MySecondUserGroup").Count());
Assert.AreEqual(2, response.Where(x => x.Authorizations == null).Count());
});
}
Running this results in an exception because the attribute tries to connect the external services and they aren't (and can't be) setup to receive requests.
So, I try to add a mocked attribute:
//** begin add mocked attribute **//
var identityService = new UserManagementService(m_Container, m_UserAuthorizationManager.Object, m_IdentityService.Object);
var IsAuthorizedAttribute = new Mock<IsAuthorizedAttribute>(MockBehavior.Strict, new object[] { SecurityAction.Demand });
IsAuthorizedAttribute.Setup(x => x.CreatePermission()).Returns(new PrincipalPermission(PermissionState.None));
TypeDescriptor.AddAttributes(identityService, IsAuthorizedAttribute.Object);
//** end add mocked attribute **//
But this one is calling the constructor of the attribute where I set up the external source. When I put this constructor in a try/catch and silently disposing the exception, I have an error on IsAuthorizedAttribute.Object object can't be found.
What are other options to not fire the attribute?
Constructors should not access externals; otherwise it will be difficult to bypass for testing, as you know.
A simple way is to make static bool field to bypass. This does not look so good but maybe enough.
public class IsAuthorizedAttribute : CodeAccessSecurityAttribute
{
// set true in the test initialization
private static bool s_byPass;
public IsAuthorizedAttribute(SecurityAction action) : base(action)
{
if (!s_byPass)
{
// setup
}
}
private static bool IsAuthorised(string entityObject, string field, char expected, ServicesConfiguration servicesConfiguration)
{
if (s_byPass) { return true; }
//check external stuff
}
}
Another better approach is to extract the external dependency to another class so that you can mock it. Mocking external dependencies is a typical pattern of a unit test.
public class IsAuthorizedAttribute : CodeAccessSecurityAttribute
{
// set mock here in the test initialization.
// I assume external accessor can be a static field.
private static ExternalAccessor m_accessor = new ExternalAccessor();
private static bool IsAuthorised(string entityObject, string field, char expected, ServicesConfiguration servicesConfiguration)
{
return m_accessor.Check();
}
}
public class ExternalAccessor
{
private bool m_initialized;
private void Setup()
{
// setup
m_initialized = true;
}
public virtual bool Check()
{
// You can call setup anytime but the constructor.
if (!m_initialized) { Setup(); }
// check external stuff
}
}

Moq a concrete class method call

I've got a setup like this with a concrete class that is instantiated inside the method I want to test. I want to mock this concrete class an not have it execute the code inside. Hence, no exception should be thrown:
public class Executor
{
public bool ExecuteAction(ActionRequest request)
{
switch (request.ActionType)
{
case ActionType.Foo:
var a = new Foo();
return a.Execute(request);
case ActionType.Bar:
var b = new Bar();
return b.Execute(request);
}
return true;
}
}
public class Foo
{
public virtual bool Execute(ActionRequest request)
{
throw new NotImplementedException();
}
}
public class Bar
{
public virtual bool Execute(ActionRequest request)
{
throw new NotImplementedException();
}
}
My NUnit test looks like this:
[Test]
public void GivenARequestToFooShouldExecuteFoo()
{
var action = new Mock<Foo>();
action.Setup(x => x.Execute(It.IsAny<ActionRequest>())).Returns(true);
var sut = new Mock<Executor>();
sut.Object.ExecuteAction(new ActionRequest
{
ActionType = ActionType.Foo
});
}
[Test]
public void GivenARequestToBarShouldExecuteBar()
{
var action = new Mock<Bar>();
action.Setup(x => x.Execute(It.IsAny<ActionRequest>())).Returns(true);
var sut = new Mock<Executor>();
sut.Object.ExecuteAction(new ActionRequest
{
ActionType = ActionType.Bar
});
}
I fiddled around with CallBase, but it didn't get me anywhere. Is there anyway I can solve this easily without dependency injection of these classes and adding interfaces? Is this possible just using Moq?
The only thing I can think to do currently is move the Execute methods into the Executor class and rename them to ExecuteFoo() and ExecuteBar(), but I have a lot of code to move so they'd have to be partial classes (sub classes?).
The problem is not with the mocking of the method but with the creation of the concrete class. The creation of Foo and Bar need to be inverted out of the Executor. It is responsible for executing the action, not creating it. with that this interface was created to handle the creation.
public interface IActionCollection : IDictionary<ActionType, Func<IExecute>> {
}
think of this as a collection of factories or a collection of creation strategies.
A common interface was created for the actions.
public interface IExecute {
bool Execute(ActionRequest request);
}
public class Foo : IExecute {
public virtual bool Execute(ActionRequest request) {
throw new NotImplementedException();
}
}
public class Bar : IExecute {
public virtual bool Execute(ActionRequest request) {
throw new NotImplementedException();
}
}
And the Executor was refactored to use dependency inversion.
public class Executor {
readonly IActionCollection factories;
public Executor(IActionCollection factories) {
this.factories = factories;
}
public bool ExecuteAction(ActionRequest request) {
if (factories.ContainsKey(request.ActionType)) {
var action = factories[request.ActionType]();
return action.Execute(request);
}
return false;
}
}
With that refactor done the Executor can be tested with fake actions.
public void GivenARequestToFooShouldExecuteFoo() {
//Arrange
var expected = true;
var key = ActionType.Foo;
var action = new Mock<Foo>();
action.Setup(x => x.Execute(It.IsAny<ActionRequest>())).Returns(expected);
var actions = new Mock<IActionCollection>();
actions.Setup(_ => _[key]).Returns(() => { return () => action.Object; });
actions.Setup(_ => _.ContainsKey(key)).Returns(true);
var sut = new Executor(actions.Object);
var request = new ActionRequest {
ActionType = ActionType.Foo
};
//Act
var actual = sut.ExecuteAction(request);
//Assert
Assert.AreEqual(expected, actual);
}
A production implementation of the factory collection can look like this
public class ActionCollection : Dictionary<ActionType, Func<IExecute>>, IActionCollection {
public ActionCollection()
: base() {
}
}
and configured accordingly with your concrete types.
var factories = ActionCollection();
factories[ActionType.Foo] = () => new Foo();
factories[ActionType.Bar] = () => new Bar();

Moq. Mock delegate input

I am trying to mock a delegate, using Moq, but so far everything im doing is in vain.
I have made a small example of how the setup is:
1.A proxy class is abstracting a WCF service
public interface IServiceProxy
{
void FooService(ServiceProxy.FooServiceDelegate service);
}
public class ServiceProxy : IServiceProxy
{
private readonly EndpointAddress _fooServiceEndpoint;
public ServiceProxy(IConfiguration configuration)
{
_fooServiceEndpoint = new EndpointAddress(new Uri(configuration.WcfServiceEndpoint));
}
public delegate void FooServiceDelegate(IFooBar proxy);
public void FooService(FooServiceDelegate service)
{
Do<IFooBar>((service.Invoke), _fooServiceEndpoint);
}
private void Do<T>(UseServiceDelegate<T> f, EndpointAddress address)
{
UsingService<T>.Use(f.Invoke, address);
}
}
2.The service definition
/// <summary>
/// This is the interface the WCF service exposes
/// </summary>
public interface IFooBar
{
string Hello(string name);
}
3.And the class that uses the proxy
public class DoFoo
{
private readonly IServiceProxy _serviceProxy;
public DoFoo(IServiceProxy serviceProxy)
{
_serviceProxy = serviceProxy;
}
public string SayHello(string name)
{
var response = string.Empty;
_serviceProxy.FooService(proxy => { response = proxy.Hello(name); });
return response;
}
}
I would like to test that the methods defined on the delegate FooServiceDelegate with the input IFooBar is in fact called and also i would like to be able to mock the responce from a methodcall on a IFooBar via the delegate.
So far my attempts has been in vain, so i hope that there are some moq experts that can help here.
Here is an example of a test, that of course does not work as it is now.
[TestClass()]
public class DoFooTests
{
[TestMethod, TestCategory("Unit")]
public void SayHelloJohn_ShouldUseServiceProxy()
{//SETUP
var serviceMock = new Mock<IFooBar>(MockBehavior.Loose);
var delegateMock = new Mock<ServiceProxy.FooServiceDelegate>(MockBehavior.Strict);
var serviceProxyMock = new Mock<IServiceProxy>(MockBehavior.Strict);
serviceProxyMock.Setup(m => m.FooService(delegateMock.Object));
var name = "John";
var response = $"Hello {name}";
//Im trying something like this (of course this does not work...)
delegateMock.Setup(m => m.Hello(name)).Returns(response);
//EXECUTE
var doFoo = new DoFoo(serviceProxyMock.Object);
var result = doFoo.SayHello(name);
//ASSERT
// Do some assertions here....
}
}
You have to call the delegate when FooService is executed:
[TestMethod]
public void SayHelloJohn_ShouldUseServiceProxy()
{
const string EXPECTED_RESULT = "Hello John";
const string NAME = "John";
var fakeServiceProxy = new Mock<IServiceProxy>(MockBehavior.Strict);
var fakeFooBar = new Mock<IFooBar>(MockBehavior.Loose);
fakeFooBar.Setup(bar => bar.Hello(NAME)).Returns(EXPECTED_RESULT);
fakeServiceProxy.Setup(proxy => proxy.FooService(
It.IsAny<ServiceProxy.FooServiceDelegate>()))
.Callback<ServiceProxy.FooServiceDelegate>(arg => arg(fakeFooBar.Object));
var target = new DoFoo(fakeServiceProxy.Object);
var result = target.SayHello(NAME);
Assert.AreEqual(EXPECTED_RESULT, result);
}
The above snippet execute proxy => { response = proxy.Hello(name); }) when you call SayHello method.

Serialization of nested Action<T> for service bus Queue

The general consensus from reading other posts is that serializing anonymous delegates and actions etc is a bad idea and brittle etc. The lifetime of these serialized actions will be very short lived but i'm open to better ideas about how to accomplish what i'm doing.
I have a web role and a worker role. The user can upload massive amounts of data that I need to split down and send to external wcf services. I need to queue this data and I just wanted a generic interface. I'd like to be able to deserialize it and call Execute() on it without having custom logic in the worker role.
I have 4 external services (may grow) each with multiple calls and there own unique parameters. I wanted a method of constructing the parameters in the web role, declaring which serviceInvoker class and interface I want to construct (generates a ChannelFactory with client credentials etc), and executing the child method with said parameters.
// Code
var queueMessage = new WorkOutMessage<IService1>(User.agent.Client.Id,
new Action<ServiceInvoker<IService1>>(serviceInvoker =>
serviceInvoker.InvokeService(proxy =>
{
using (new OperationContextScope((IContextChannel)proxy))
{
OperationContext.Current.OutgoingMessageHeaders.ReplyTo = new EndpointAddress("https://someAddress.com/");
OperationContext.Current.OutgoingMessageHeaders.MessageId = new System.Xml.UniqueId(head.CorrelationID);
proxy.SomeChildFunction(envelope);
}
})));
var stream = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(stream, queueMessage;
var brokeredMessage = new BrokeredMessage(stream) { CorrelationId = correlationId };
// Formatter.Serialize throws an exception
Type '<MyController>+<>c__DisplayClassc' in Assembly '<MyDll>, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
// Classes
public interface IQueueProxyMessage
{
int Attempts();
bool Execute();
}
[Serializable]
public class WorkOutMessage<T> : IQueueProxyMessage where T : class
{
public Guid clientId { get; set; }
public Action<ServiceInvoker<T>> action { get; set; }
public int attempts { get; set; }
public WorkOutMessage(Guid clientId, Action<ServiceInvoker<T>> action)
{
this.clientId = clientId;
this.action = action;
this.attempts = 0;
}
public int Attempts()
{
return this.attempts;
}
public bool Execute()
{
this.attempts++;
try
{
var config = InfrastructureConfiguration.Instance;
var storage = new AzureStorageService();
var db = new DbContext(config.azure.dbConnectionString,
DbValidationMode.Enabled,
DbLazyLoadingMode.Disabled,
DbAutoDetectMode.Enabled);
var client = db.Client.Include(x => x.Organisation)
.Include(x => x.Certificate)
.Where(x => x.Active
&& x.Organisation.Active
&& x.Certificate != null
&& x.Id == this.clientId)
.FirstOrDefault();
if(client != null)
{
X509Certificate2 clientCert;
string clientCertContentType;
byte[] clientCertContent;
if (storage.GetBlob(AzureBlobType.Certificate, client.Certificate.StorageId.ToString(), out clientCertContentType, out clientCertContent))
{
var base64EncodedBytes = Encoding.Unicode.GetString(clientCertContent);
clientCert = new X509Certificate2(Convert.FromBase64String(base64EncodedBytes), "test", X509KeyStorageFlags.PersistKeySet);
if(clientCert != null)
{
var serviceInvoker = new ServiceInvoker<T>(client.Id, "test", clientCert, config.publicCertificate);
if(serviceInvoker != null)
{
this.action.Invoke(serviceInvoker);
}
// error
}
// error
}
// error
}
else
{
}
return true;
}
catch (Exception ex)
{
return false;
}
}
Obviously my serialization knowledge is pretty non-existant. which is why I thought this would work in the first place. Is there any way to re-architect this so I can still specify what serviceInvoker to use, what method and pass the parameters?
Edit: the code where I try to use BinaryFormatter and Exception
Edit2: This is a bad idea, i'm going to pass the data and reconstruct the class on the worker.

Using Moq to modify the argument to a stubbed void method

I have a bit of a perfect storm that's preventing me from testing a class. The class is a RestClient that's wrapping an in-house HttpClient (which I cannot modify). The ExecuteMethod method on the HttpClient is void. It accepts an IHttpMethod, and it modifies this object based on the response from the server. I want to mock out ExecuteMethod so that it modifies the IHttpMethod for me. I'm trying to use Callback to achieve this, but it's not working.
Here's the code that sends the request:
var httpClient = this.httpClientFactory.CreateHttpClient();
httpClient.ExecuteMethod(method);
var response = this.GetResourceResponse<T>(method.ResponseBodyAsStream.AsString());
response.ResponseHeaders = method.ResponseHeaders;
response.Status = method.StatusCode.ToString();
response.StatusCode = (int)method.StatusCode;
return response;
And here's my attempt at mocking:
var mockHttpMethod = new Mock<IHttpMethod>();
mockHttpMethod.Setup(m => m.ResponseBodyAsStream).Returns(new MemoryStream(Encoding.UTF8.GetBytes("foo")));
var modifyHttpMethod = new Action<IHttpMethod>(m =>
{
m = mockHttpMethod.Object;
});
var mockHttpClient = new Mock<IHttpClient>();
mockHttpClient.Setup(c => c.ExecuteMethod(It.IsAny<IHttpMethod>()))
.Callback<IHttpMethod>(modifyHttpMethod);
var mockHttpClientFactory = new Mock<ILegalHoldHttpClientFactory>();
mockHttpClientFactory.Setup(f => f.CreateHttpClient()).Returns(mockHttpClient.Object);
var restClient = new RestClient(mockHttpClientFactory.Object);
When the modifyHttpMethod action is executed, I observe two things, both of which I expect:
The incoming IHttpMethod (m) has the properties I expect it to have.
After assigning the mock object to m, it contains the stubbed values that I setup in my test.
However, after the callback is executed and control is returned to my application code, my method variable still has its old values that I saw in step 1 above, which causes a null reference exception when trying to read method.ResponseBodyAsStream.
Is what I'm trying to do even achievable? If so, how? Thanks!
I've replicated your setup vis a vis mocking, and can't find any issues with it:
public interface IHttpMethod
{
MemoryStream ResponseBodyAsStream { get; set; }
}
public interface IHttpClient
{
void ExecuteMethod(IHttpMethod method);
}
public class HttpClient : IHttpClient
{
#region IHttpClient Members
public void ExecuteMethod(IHttpMethod method)
{
}
#endregion
}
public class Factory
{
public virtual IHttpClient CreateHttpClient()
{
return new HttpClient();
}
}
public class ClassUnderTest
{
private readonly Factory _factory;
public ClassUnderTest(Factory factory)
{
_factory = factory;
}
public string GetResponseAsString(IHttpMethod method)
{
var myClient = _factory.CreateHttpClient();
myClient.ExecuteMethod(method);
return method.ResponseBodyAsStream.ToString();
}
}
[TestClass]
public class ScratchPadTest
{
[TestMethod]
public void SampleTest()
{
var mockHttpMethod = new Mock<IHttpMethod>();
mockHttpMethod.Setup(x => x.ResponseBodyAsStream).Returns(new MemoryStream(Encoding.UTF8.GetBytes("foo")));
var modifyHttpMethod = new Action<IHttpMethod>(m =>
{
m = mockHttpMethod.Object;
});
var mockHttpClient = new Mock<IHttpClient>();
mockHttpClient.Setup(c => c.ExecuteMethod(It.IsAny<IHttpMethod>())).Callback<IHttpMethod>(modifyHttpMethod);
var myFactoryStub = new Mock<Factory>();
myFactoryStub.Setup(f => f.CreateHttpClient()).Returns(mockHttpClient.Object);
var myCut = new ClassUnderTest(myFactoryStub.Object);
Assert.IsNotNull(myCut.GetResponseAsString(mockHttpMethod.Object));
}
}
That test passes, meaning that the memory stream is not null (otherwise an exception would be generated). The only X factor that I can see is your AsString() extension method (I'm assuming that's an extension method as intellisense doesn't show it to me on MemoryStream). Could your problem be in there?
And, by the way, what you're trying to do is almost certainly achievable with Moq.

Categories

Resources