-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
InvalidCastException : Unable to cast object of type 'T' to type 'Moq.IMocked`1[T]' #33
Comments
Ok, so there's two things going on here. First, there is a bug here, but only in the sense that we're not throwing the right exception if you attempt to mock something that we cannot mock. We'll fix that so the right exception gets thrown. Secondly, the reason an exception is being thrown is that this integration doesn't let you create a mock that does not have a public constructor with zero parameters. This is partly due to a restriction on how we create mocks, but also because it's a slight code smell to mock a class with constructor parameters. You normally try to mock interfaces, because they don't have a problem. Additionally, in your original test, you don't actually have any object under test: [Fact]
public void RunTest()
{
using (var mock = AutoMock.GetLoose())
{
// Mock a dependency, check, that's all fine.
mock.Mock<IDependency>().Setup(s => s.DoSomethingExternal()).Returns(7);
// Mock another class...
// ...oh, but we're not actually testing the class itself,
// we're testing a mock!
var sut = mock.Mock<SUTWithDependency>();
sut.CallBase = true;
sut.Setup(s => s.DoSomeThing()).Returns(30);
var res = sut.Object.Testing();
// Assert something (but we're actually testing mock behaviour).
Assert.Equal(42, res);
}
} Your object under test should be created, using the [Fact]
public void RunTest()
{
using (var mock = AutoMock.GetLoose())
{
// Mock a dependency, check, that's all fine.
mock.Mock<IDependency>().Setup(s => s.DoSomethingExternal()).Returns(7);
// Now create the class that is actually under test.
// This will correctly inject IDependency into the constructor.
var underTest = mock.Create<SUTWithDependency>();
var res = underTest.Testing();
// Assert something. We're now actually testing the class.
Assert.Equal(42, res);
}
} I hope that helps. I'm progressing a fix for throwing the right defect now. |
Ok, since 5.0.1 there is another exception. As alistairjevans wrote, I should instantiate with the SUTWithDependency class with the Create method. But how do I achieve this??? Best Regards |
My question would be, why are you mocking SUTWithDependency at all? What class is actually under test here? |
Oh its a business application with heavy business logic. SUT is a service containing business logic. It depends on other services (with biz logic) as well as EF Core repos. As well SUT is sometimes a composition of multiple methods. When I run a test I only want to test a single method and not all methods, services or repos it depends on. |
Ok, well a general principle would be that any internal dependencies (e.g. private methods) should be part of the test. If they cannot be, then it suggests some of the contents of those methods should be factored out into another service, that can itself then be mocked and injected. |
When trying to set up a partial mocked test I get the following error:
InvalidCastException : Unable to cast object of type 'T' to type 'Moq.IMocked`1[T]'
In this issue it was marked as resolved:
#9
I'm using XUnit 2.4.1 and Autofac.Extras.Moq 5.0.0
What I've found out so far is. As long as I mock a class without dependencies it works. As soon as there is a constructor injection needed the error occurs. I've made two tests for verifying the issue. The first runs fine, the second one throws the error:
The text was updated successfully, but these errors were encountered: