Cannot assign to .. because it is a group method - c#

I am using Moq to write test cases and when I try to assign the mock function within the constructor it comes up with the error saying that I cannot assign it because the target method is a group method however there is only one method defined.
I have written an interface etc. as follows:
...
public interface IRSPPortal
{
string GetOrderStatus(OrderInfo OrderNum);
}
public class RSPPortal : IRSPPortal
{
public RSPPortal(IRSPPortal GetOrderStatusMock)
{
this.GetOrderStatus = GetOrderStatusMock; //This line gives the error
}
public string GetOrderStatus(OrderInfo OrderNum)
{
//stuff done here to access a database
}
}
...
There is only one method GetOrderStatus(OrderInfo OrderNum) so I don't know why it has classified it as a method group. What is the simplest way to overcome this error?
I have tried to use
this.GetOrderStatus = GetOrderStatusMock.GetOrderStatus;
but that didn't work either.
Thanks everyone.

That's not how Moq works. If you want to mock IRSPPortal:
Mock<IRSPPortal> rspPortalMock = new Mock<IRSPPortal>();
rspPortalMock.Setup(a => a.GetOrderStatus(It.IsAny<OrderInfo>())).Returns(<string you want returned from the mocked method>);
Now you have a mock of IRSPPortal that will return whatever string you want from GetOrderStatus.
To use that mocked object just pass in rspPortalMock.Object to whatever class is using IRSPPortal.

Related

Not able to Mock Indexers in C# using SetupGet

I have the following Interfaces with get properties and one indexer.
public interface IDummy
{
public string Name{get;set;}
public IDummyList DummyChildren{get;}
}
public interface IDummyList
{
IDummy this[string name]{get;}
}
Now I am trying to mock the IDummy like this
Mock<IDummy> mockDummy = new Mock<IDummy>{DefaultValue = DefaultValue.Mock}
Mock<IDummy> mockDummyChildren = new Mock<IDummy>{DefaultValue = DefaultValue.Mock}
mockDummy.SetupGet(x=>x.Name).Returns("XYZ");
mockDummyChildren.SetupGet(x=>x.DummyChildren["ABC"]).Return(mockDummy.Object)
But the above code doesn't set the mockdata for DummyChildren. I am trying to understand why it is not doing that.
Since the properties are read only so I cannot set it directly. So need the Mock data to be used in the original function to test.
Please let me know if there is any enhancement or I am missing out something here.
Thanks.

How can I add a default constructor and have it call another constructor and use the default values?

I have this code:
public class NewFrame
{
public NewFrame(string iconSource = Const.Car,
string iconColor = Const.Red)
{
When I try and use it then it's telling me I am missing a default constructor. How can I add one of these and still make the code use the default values for iconBackgroundColor and IconSource? I thought that adding in those defaults with the = Const. would make it work but it seems like it doesn't think my constructor is a default (with no params).
You just have to add another empty overload and call the required constructor with defaults. See below:
public class NewFrame
{
public NewFrame() : this(Const.Car, Const.Red){
}
public NewFrame(string iconSource,
string iconColor)
{
...
}
}
By having two optional parameters, you don't actually create 4 different constructor declarations under the hood (one with both parameters, one with the first parameter, one with the second parameter, and one with neither). There is still only one constructor, with two parameters. It's just that C# recognises that the parameters are optional, and has syntactic sugar to let you omit them when you call the constructor.
However, if you use reflection to create an instance of your class (probably whatever the thing that requires a default constructor is doing), and you attempt to invoke the parameterless constructor, it won't find one, because there is no syntactic sugar in reflection.
Here is an example:
class MainClass
{
public static void Main(string[] args)
{
Type t = typeof(MainClass);
object o = Activator.CreateInstance(t, 1);
Console.WriteLine(o);
}
public MainClass(int a = 10)
{
}
}
If you use typeof(MainClass).GetConstructors(), it will tell you that there is only one.
To actually declare a default constructor, you can do:
public class NewFrame
{
public NewFrame(string iconSource = Const.Car,
string iconColor = Const.Red)
{
...
}
public NewFrame() : this(Const.Car, Const.Red) { }
}
For what it's worth, when I do something like this, I take the route that #VyacheslavBenedichuk's answer is showing.
I'm not sure what your complaint is. This code compiles for me:
public class TestConstructor
{
public TestConstructor(string what = Const.Car, string color = Const.Red)
{
}
public static void Test()
{
var tc = new TestConstructor();
}
public class Const
{
public const string Car = "car";
public const string Red = "red";
}
}
What do your definitions of Const.Car and Const.Red look like? Where are you seeing the error?
But, if you use something that requires a default constructor, then this will not work. For example, this will fail at runtime:
var tc2 = Activator.CreateInstance(typeof(TestConstructor));
Please, when you are reporting an error, describe it exactly - in particular say whether it's a runtime or a compile-time error, the exact wording of the error, and the context in which the error occurs. In this case (the call to CreateInstance) will result in a System.MissingMethodException: 'No parameterless constructor defined for this object.'
In this case, you need to follow #VyacheslavBenedichuk's advice

Method cannot explicitly call operator or accessor

I added .dll: AxWMPLib and using method get_Ctlcontrols() but it show error like:
AxWMPLib.AxWindowsMediaPlayer.Ctlcontrols.get': cannot explicitly call operator or accessor
This is my code using get_Ctlcontrols() method:
this.Media.get_Ctlcontrols().stop();
I don't know why this error appears. Can anyone explain me and how to resolve this problem?
It looks like you are trying to access a property by calling explicitly its get method.
Try this (notice that get_ and () are missing):
this.Media.Ctlcontrols.stop();
Here is a small example about how properties work in C# - just to make you understand, this does not pretend to be accurate, so please read something more serious than this :)
using System;
class Example {
int somePropertyValue;
// this is a property: these are actually two methods, but from your
// code you must access this like it was a variable
public int SomeProperty {
get { return somePropertyValue; }
set { somePropertyValue = value; }
}
}
class Program {
static void Main(string[] args) {
Example e = new Example();
// you access properties like this:
e.SomeProperty = 3; // this calls the set method
Console.WriteLine(e.SomeProperty); // this calls the get method
// you cannot access properties by calling directly the
// generated get_ and set_ methods like you were doing:
e.set_SomeProperty(3);
Console.WriteLine(e.get_SomeProperty());
}
}

Fail try/catch block reading a csv

I'm unit testing my C# application that Parses a CSV. I'm at 94% code coverage, because I can't force it to fail the try/catch blocks... I'm using CsvHelper from Nuget http://joshclose.github.io/CsvHelper
public void ParseCsv([FromBody] string csvText)
{
var parseCsv = new XsvData(new[] { "\t", "," });
try
{
using (var reader = new XsvReader(new StringReader(csvText)))
{
parseCsv.Read(reader, headerExists: true);
}
}
catch (Exception)
{
var response = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent("Unable to read CSV."),
ReasonPhrase = "Invalid CSV"
};
throw new HttpResponseException(response);
}
}
I've tried passing the most obscure strings I could think of to it, but it makes it through this, and errors out later on in the function..
[TestMethod]
//[ExpectedException(typeof(HttpResponseException))]
public void TestUploadCsv_UploadingCsvNonCsv()
{
const string csvText = "fhfhk#- jhjfh#ajh- fjkqeqir%hjewq#hf- ujewqh$phfuw \n hfwu- ihfq&if*u#q- afuhwu- fhiue#wfhiuewhiuf";
var context = GetMyFakeEntityDatabase();
var controller = new MyController(context);
controller.ParseCsv(csvText);
}
After the try/catch blocks, I have a section that enforces all the headers exist, and it fails there, but it should be failing during the reading, for this example. How do I force my unit test to fail? Any help is appreciated! Thanks in advance.
Use the Provider Pattern and interfaces instead of concrete types, then run your unit tests by substituting mock objects that will throw the exceptions.
In detail:
Extract Interface IXsvReader from XsvReader
Implement a new concrete instance of IXsvReader that throws exceptions on Read. Create one concrete implementation class for each error you expect to handle separately (in this case, you only need one).
In the class that contains the ParseCSV method, have a property for an IXsvProvider that is settable. In the constructor for that same class, set that property to a default provider that will return a "real" reader. This interface has only one method, GetXsvReader(string text)
In your test class, new up the class with the ParseCSV function, then inject an IXsvProvider(s) that returns your "dummy" IXsvReader that simply throws exceptions whenever you try to use the method.
You should use Inversion of Control and inject the dependency into the controller instead of creating it in controller action. This way you can mock out the reader, and have it throw an except instead.
I'm going to write this example in terms of CsvHelper since that's what you say you are using, even though the example doesn't look like it.
Roughly:
public class MyController : Controller
{
private readonly ICsvReader csv;
public MyController( ICsvReader csv )
{
this.csv = csv;
}
}
public class CsvReaderMock : ICsvReader
{
public void Read()
{
throw new Exception();
}
}
Now you can use your mock ICsvReader when testing, and it will throw an exception.
Also, you should only ever test a single method. If your method has dependencies, you should be passing them in instead of creating them, so you can test only the code in that method, and not of the classes it creates.
I solved this by just passing it null, like juharr recommended in the comments.

Ninject default contextual binding

I have an interface with a few different concrete implementations. I am trying to give Ninject a default to use and only use the other implementation if a name matches. For instance, I have the following bindings.
Bind<ISomething>().To<DefaultSomething>()
Bind<ISomething>().To<OtherSomething>().Named("55abd8b8-097f-4e1c-8d32-95cc97910604");
What I would like is if the Named section doesn't match, to use the DefaultSomething implementation. When I pass in the explicitly bound guid, it works fine. When I pass in any other guid I get the "No matching bindings are available" exception.
Bind<ISomething>().To<OtherSomething>().Named("55abd8b8-097f-4e1c-8d32-95cc97910604");
Bind<ISomething>().To<DefaultSomething>()
Bind<ISomething>().To<DefaultSomething>()
Bind<ISomething>().To<OtherSomething>().When(ctx => ctx.Service != null && ctx.Service.Name == "55abd8b8-097f-4e1c-8d32-95cc97910604");
I have also tried using .When to check the binding and I have tried reversing the order like below however I am never able to bind unless I pass in the Guid that is explicitly named.
This article seems to indicate that default bindings work, so I must be doing something wrong. Any suggestions?
Edit: Here is a complete example showing the problem I am trying to solve. The desired behavior is for kernel.Get<INumber>("Three").Write() to return "Unknown Number"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
namespace NinjectTest
{
interface INumber
{
string Write();
}
class UnknownNumber : INumber
{
public string Write()
{
return "Unknown Number";
}
}
class One : INumber
{
public string Write()
{
return "1 = One";
}
}
class Two : INumber
{
public string Write()
{
return "2 = Two";
}
}
class Program
{
static void Main(string[] args)
{
StandardKernel kernel = new StandardKernel();
kernel.Bind<INumber>().To<UnknownNumber>();
kernel.Bind<INumber>().To<One>().Named("One");
kernel.Bind<INumber>().To<Two>().Named("Two");
Console.WriteLine(kernel.Get<INumber>("One").Write());
Console.WriteLine(kernel.Get<INumber>("Two").Write());
Console.WriteLine(kernel.Get<INumber>("Three").Write());
Console.ReadLine();
}
}
}
You completely missunderstood named bindings:
Giving a binding a name is NOT a condition. You will still get all of them when requesting them without a constraint. Adding a name changes absolutely nothing on its own.
Requesting an instance using a name adds the constraint:
only bindings whose name matches the given one shall be returned
In your case, you gave me an instance whose binding's name is "three". And you expect it to return UnknownNumber, which does not even have a name.
This can be achieved by either
passing a parameter and adding conditions to the bindings that check if the parameter matches, or
passing a constraint that fits the name or the unnamed instance and declare the unnamed one implicit.
Option 1:
public class CustomerIdParameter : Parameter
{
public CustomerIdParameter(string id) : base("CustomerId", (object)null, false)
{
this.Id = id;
}
public string Id { get; private set; }
}
kernel.Bind<ISomething>().To<Default>();
kernel.Bind<ISomething>().To<Other>()
.When(r => r.Parameters.OfType<CustomerIdParameter>()
.Single().Id == "SomeName");
kernel.Get<IWeapon>(new CustomerIdParameter("SomeName")).ShouldBeInstanceOf<Sword>();
I leave it up to you to write the extension methods to make the definition and resolve easier.
Option 2:
Bind<ISomething>().To<Default>().Binding.IsImplicit = true;
Bind<ISomething>().To<Other>().Named("SomeName")
public static T GetNamedOrDefault<T>(this IKernel kernel, string name)
{
return kernel.Get<T>(m => m.Name == null || m.Name == name);
}
But honestly I think what you want to do doesn't seem to be a proper design:
Keep your access to the kernel to an absolute minimum. What you're doing here is a ServiceLocator-like usage of Ninject.
If no binding is available for an expected instance, I'd rather expect an exception than using a default instance because this is a bug.
You can also simply add a condition for your binding to not have a condition, like so:
kernel.Bind<IObject>().To<Object1>().When(
x => x.ParentContext != null && !x.ParentContext.Binding.IsConditional)
.InRequestScope();
kernel.Bind<IObject>().To<Object2>().InRequestScope()
.Named("WCFSession");
When doing a standard Inject without a Name specified, the first binding will be used. When specifying a name, the named binding will be used. It's not the prettiest solution, but it works.
It's quite possible to do this in Ninject, it just doesn't happen to be the way the resolution behaves by default. The IKernel.Get<T> extension does not ask for the "default" binding, it asks for any binding; in other words it does not apply any constraints. If there is more than one matching binding then it throws an exception to that effect.
Try out these two extension methods:
static class KernelExtensions
{
public static T GetDefault<T>(this IKernel kernel)
{
return kernel.Get<T>(m => m.Name == null);
}
public static T GetNamedOrDefault<T>(this IKernel kernel, string name)
{
T namedResult = kernel.TryGet<T>(name);
if (namedResult != null)
return namedResult;
return kernel.GetDefault<T>();
}
}
The first one gets the "default" binding - i.e. whichever one you've bound that has no name. The second one tries to get a named binding, but if it doesn't find that, then it reverts to the default.
Of course, Remo is not wrong either; you should avoid using Ninject or any other container this way unless you have a particularly good reason to. This is the Service Locator (anti-)pattern, not true dependency injection. You should be using the When syntax for conditional bindings, either using complex conditions or just decorating the classes which need special bindings, i.e.:
Bind<IFoo>().To<SpecialFoo>().WhenInjectedInto<ClassThatNeedsSpecialFoo>();
or...
Bind<IFoo>().To<SpecialFoo>().WhenMemberHas<SpecialAttribute>();
class InjectedClass
{
public InjectedClass([Special]IFoo) { ... }
}
That is the right way to handle default and conditional bindings. Named bindings are really only useful when you're trying to implement a factory pattern and you want to wrap the IoC container in your custom factory. That's OK, but please use it sparingly, as you end up throwing away many/most of the benefits of dependency injection that way.
Alternatively, you could actually implement your own activation behaviour and use it to override the default in Ninject - everything is modular and gets shoved into the "Components" collection. But this is not for the faint of heart, so I don't plan on including a detailed tutorial here.
I checked the ParaSwarm's solution and it worked for a simple test project. But in a real project his solution didn't fit. I managed to solve it by the following code:
const string specificServiceName = "For" + nameof(SpecificService);
kernel.Bind<IService>()
.To<DefaultService>()
.When(x => x.Constraint == null || !x.Constraint(new BindingMetadata { Name = specificServiceName }))
.InTransientScope();
kernel.Bind<IService>()
.To<SpecificService>()
.InTransientScope()
.Named(specificServiceName);
PS: my answer does not solve the author's problem, but it can help someone with searching similar problem (as ParaSwarm's answer helps me)

Categories