简体   繁体   中英

RuntimeBinderException thrown from NUnit's Assert.That for dynamic objects

I have an NUnit test case that asserts the type set in the new ViewBag property of an MVC Controller.

So the action body has

 using (IRepository repository = _repositoryProvider.GetRepository())
 {
      ViewBag.Articles = repository.Get<Articles>()
      return View();
 }

and trying to test this as so

 var mockProvider = new Mock<IRepositoryProvider>();
 var mockRepository = new Mock<IRepository>();
 mockProvider.Setup(m => m.GetRepository()).Returns(mockRepository.Object);
 mockRepository.Setup(m => m.Get<Articles>()).Returns(It.IsAny<IEnumerable<Articles>>);
 var homeController = new HomeController(mockProvider.Object);
 var viewResult = homeController.Index();
 Assert.That(homeController.ViewBag.Articles, Is.TypeOf<IEnumerable<Articles>>());

Now, the "That" call throws a RuntimeBinderException

 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : 
 The call is ambiguous between the following methods or properties:  

 NUnit.Framework.Assert.That(NUnit.Framework.Constraints.ActualValueDelegate, 
 NUnit.Framework.Constraints.IResolveConstraint) and 

 NUnit.Framework.Assert.That(NUnit.Framework.TestDelegate, 
 NUnit.Framework.Constraints.IResolveConstraint)

Has anyone seen an exception for custom dynamic objects? I have other test cases where strings are set in the ViewBag and they don't run into this exception

I also tried "as dynamic" as in, but that didn't help either

ViewBag.Articles = repository.Get<Articles>() as dynamic;

This is a super old question so you've probably found your answer by now, but since this was the first google result for my problem (and this page didn't have an answer on it) I figured it'd be good to include a solution.

I believe what was happening is that as pointed out by the other poster, there was a problem with your mocks causing homeController.ViewBag.Articles to be null. nUnit has a hard time with nulls on a dynamic object which was causing the RuntimeBinderException.

In your case fixing your mock would solve the issue, but in the general case (ie someone who actually wants to use nUnit with a null on a dynamic object), the fix is to cast the dynamic value to the concrete type you want to check against and it will solve the ambiguous call:

Assert.That((IEnumerable<Articles>)homeController.ViewBag.Articles, Is.TypeOf<IEnumerable<Articles>>());

You have error in setup part of Your unit test

I don't know how to enter angle bracket in code below so I will use [

mockRepository.Setup(m => m.Get[Articles]()).Returns(It.IsAny[IEnumerable[Articles]];

'Returns' method should receive object that method should return. It.IsAny is used to specify input parameters to the method. You have to use it like that.


var mock = new Mock[ITestInterface]();
mock.Setup(m => m.GetListOfMyClass(It.IsAny[int]())).Returns(new List[MyClass]());
var result = mock.Object.GetListOfMyClass(10);
Assert.That(result, Is.TypeOf[List[MyClass]]());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM