Autofac mock - 如何 setup/fake 来自依赖项中特定方法的数据?
Autofac mock - How do I setup/fake data from specific methods in dependencies?
我很可能是单元测试、Autofac 和 mock 的新手,这相对容易,但我很难弄明白。
我有一个 class SystemUnderTest
和两个方法 GetValueOne
和 GetValueTwo
.
public class SystemUnderTest : ISystemUnderTest
{
private readonly IDependency _dependency;
public SystemUnderTest(IDependency dependency)
{
_dependency = dependency;
}
public string GetValueOne()
{
return _dependency.GetValueOne();
}
public string GetValueTwo()
{
return _dependency.GetValueTwo();
}
}
public interface ISystemUnderTest
{
string GetValueOne();
string GetValueTwo();
}
这些方法从依赖项中获取数据。
public class Dependency : IDependency
{
public string GetValueOne()
{
return "get-value-one";
}
public string GetValueTwo()
{
return "get-value-two";
}
}
public interface IDependency
{
string GetValueOne();
string GetValueTwo();
}
我试图从其中一种方法(“GetValueTwo
”)伪造数据,因此它返回 "expected value"
而不是 "get-value-two"
,这通常是依赖性 returns.
[Fact]
public async Task Test_SystemUnderTest()
{
using (var mock = AutoMock.GetLoose())
{
// Setup
mock.Mock<IDependency>().Setup(x => x.GetValueTwo()).Returns("expected value");
// Configure
mock.Provide<IDependency, Dependency>();
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.Equal("get-value-one", actual_GetValueOne);
Assert.Equal("expected value", actual_GetValueTwo);
}
}
我测试的第一部分,Setup
部分,似乎没有任何效果,可能是因为我做错了一些基本的事情。
有人知道如何拯救我的一天吗?
不是编写单元测试的专家,但我很确定通过使用带有两个类型参数的 Provide
,您会覆盖之前所做的 Setup
部分。据我了解,应该使用 Provide
方法来提供您自己的目标接口模拟实现,因此同时使用带有两个类型参数的 Provide
和用于相同依赖项的 Setup
不会感觉。
因此您可以将 Dependency
实现的 GetValueTwo
修改为 return "expected value"
并使用其余未修改的代码,或者您可以将模拟实例提供给具有一种类型参数的 Provide
方法,以及先前设置的两种方法,如下所示:
[Fact]
public async Task Test_SystemUnderTest()
{
using (var mock = AutoMock.GetLoose())
{
var mockedDependency = mock.Mock<IDependency>();
// Setup
mockedDependency.Setup(x => x.GetValueOne()).Returns("get-value-one");
mockedDependency.Setup(x => x.GetValueTwo()).Returns("expected value");
// The following line is not even necessary
mock.Provide<IDependency>(mockedDependency.Object);
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.Equal("get-value-one", actual_GetValueOne);
Assert.Equal("expected value", actual_GetValueTwo);
}
}
Dependency
实现的成员需要有虚拟成员,以便在进行部分模拟时能够覆盖它们。
public class Dependency : IDependency {
public virtual string GetValueOne() {
return "get-value-one";
}
public virtual string GetValueTwo() {
return "get-value-two";
}
}
然后类似于另一个答案中的建议,您将改为模拟实现,确保使其能够调用基本成员并仅设置您需要覆盖的成员。
public void Test_SystemUnderTest() {
using (var mock = AutoMock.GetLoose()) {
// Setup
var dependency = mock.Mock<Dependency>();
dependency.CallBase = true;
dependency.Setup(x => x.GetValueTwo()).Returns("expected value");
// Configure
mock.Provide<IDependency>(dependency.Object);
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.AreEqual("get-value-one", actual_GetValueOne);
Assert.AreEqual("expected value", actual_GetValueTwo);
}
}
如果需要模拟的实现成员可以被覆盖(即virtual
),则上述内容在执行时通过。
我很可能是单元测试、Autofac 和 mock 的新手,这相对容易,但我很难弄明白。
我有一个 class SystemUnderTest
和两个方法 GetValueOne
和 GetValueTwo
.
public class SystemUnderTest : ISystemUnderTest
{
private readonly IDependency _dependency;
public SystemUnderTest(IDependency dependency)
{
_dependency = dependency;
}
public string GetValueOne()
{
return _dependency.GetValueOne();
}
public string GetValueTwo()
{
return _dependency.GetValueTwo();
}
}
public interface ISystemUnderTest
{
string GetValueOne();
string GetValueTwo();
}
这些方法从依赖项中获取数据。
public class Dependency : IDependency
{
public string GetValueOne()
{
return "get-value-one";
}
public string GetValueTwo()
{
return "get-value-two";
}
}
public interface IDependency
{
string GetValueOne();
string GetValueTwo();
}
我试图从其中一种方法(“GetValueTwo
”)伪造数据,因此它返回 "expected value"
而不是 "get-value-two"
,这通常是依赖性 returns.
[Fact]
public async Task Test_SystemUnderTest()
{
using (var mock = AutoMock.GetLoose())
{
// Setup
mock.Mock<IDependency>().Setup(x => x.GetValueTwo()).Returns("expected value");
// Configure
mock.Provide<IDependency, Dependency>();
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.Equal("get-value-one", actual_GetValueOne);
Assert.Equal("expected value", actual_GetValueTwo);
}
}
我测试的第一部分,Setup
部分,似乎没有任何效果,可能是因为我做错了一些基本的事情。
有人知道如何拯救我的一天吗?
不是编写单元测试的专家,但我很确定通过使用带有两个类型参数的 Provide
,您会覆盖之前所做的 Setup
部分。据我了解,应该使用 Provide
方法来提供您自己的目标接口模拟实现,因此同时使用带有两个类型参数的 Provide
和用于相同依赖项的 Setup
不会感觉。
因此您可以将 Dependency
实现的 GetValueTwo
修改为 return "expected value"
并使用其余未修改的代码,或者您可以将模拟实例提供给具有一种类型参数的 Provide
方法,以及先前设置的两种方法,如下所示:
[Fact]
public async Task Test_SystemUnderTest()
{
using (var mock = AutoMock.GetLoose())
{
var mockedDependency = mock.Mock<IDependency>();
// Setup
mockedDependency.Setup(x => x.GetValueOne()).Returns("get-value-one");
mockedDependency.Setup(x => x.GetValueTwo()).Returns("expected value");
// The following line is not even necessary
mock.Provide<IDependency>(mockedDependency.Object);
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.Equal("get-value-one", actual_GetValueOne);
Assert.Equal("expected value", actual_GetValueTwo);
}
}
Dependency
实现的成员需要有虚拟成员,以便在进行部分模拟时能够覆盖它们。
public class Dependency : IDependency {
public virtual string GetValueOne() {
return "get-value-one";
}
public virtual string GetValueTwo() {
return "get-value-two";
}
}
然后类似于另一个答案中的建议,您将改为模拟实现,确保使其能够调用基本成员并仅设置您需要覆盖的成员。
public void Test_SystemUnderTest() {
using (var mock = AutoMock.GetLoose()) {
// Setup
var dependency = mock.Mock<Dependency>();
dependency.CallBase = true;
dependency.Setup(x => x.GetValueTwo()).Returns("expected value");
// Configure
mock.Provide<IDependency>(dependency.Object);
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.AreEqual("get-value-one", actual_GetValueOne);
Assert.AreEqual("expected value", actual_GetValueTwo);
}
}
如果需要模拟的实现成员可以被覆盖(即virtual
),则上述内容在执行时通过。